首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不能在maven中同时使用jacoco JVM args和尽力而为的JVM args。

不能在maven中同时使用jacoco JVM args和尽力而为的JVM args。
EN

Stack Overflow用户
提问于 2014-04-21 02:54:14
回答 10查看 62K关注 0票数 75

我正在使用maven和jacoco插件来生成代码覆盖率指标。我有一些困难,在配置与java选项所需的jacoco插件的保险火插件。我已经在Stack溢出上看到了一些关于这个问题的答案,但是有些东西对我来说不管用。

我有一个多模块项目,我的一个模块配置了这样的插件:

foo/pom.xml

代码语言:javascript
运行
复制
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>-XX:MaxPermSize=512m</argLine>
    </configuration>
  </plugin>
</plugins>

这如预期的那样起作用。

现在,我希望将jacoco合并以获得代码覆盖率指标,因此我添加了一个CodeCoverage配置文件,用于处理所有的jacoco配置:

parent/pom.xml

代码语言:javascript
运行
复制
<profile>
  <id>CodeCoverage</id>
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.jacoco</groupId>
          <artifactId>jacoco-maven-plugin</artifactId>
          <executions>
            <execution>
              <id>jacoco-initialize</id>
              <goals><goal>prepare-agent</goal></goals>
              <configuration>
                <propertyName>surefire.argLine</propertyName>
              </configuration>
              ...
            </execution>
          <executions> 
        </plugin>
      </plugins>
    </pluginManagement>
  </build>   
</profile>

这里可以看到,如果指定了CodeCoverage配置文件,那么将jacoco插件配置为使用surefire.argLine属性,而该属性用于为偏火插件配置argLine

然后,我更新了foo模块的pom.xml文件,以使用由jacoco插件生成的surefire.argLine属性:

foo/pom.xml

代码语言:javascript
运行
复制
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>${surefire.argLine} -XX:MaxPermSize=512m</argLine>
    </configuration>
  </plugin>
</plugins>

这种方法是在jacoco插件文档中指定的(参见1)。

当我使用CodeCoverage配置文件构建foo模块时,我会看到以下内容:

代码语言:javascript
运行
复制
[foo] $ mvn clean install -X -PCodeCoverage
...
[INFO] --- jacoco-maven-plugin:0.7.0.201403182114:prepare-agent (jacoco-initialize) @ foo ---
[INFO] surefire.argLine set to -javaagent:...\\org.jacoco.agent\\0.7.0.201403182114\\org.jacoco.agent-0.7.0.201403182114-runtime.jar=destfile=...\foo\\\target\\coverage-reports\\jacoco-ut.exec
...
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator -->
[DEBUG]   (s) argLine = -javaagent:...\\org.jacoco.agent\\0.7.0.201403182114\\org.jacoco.agent-0.7.0.201403182114-runtime.jar=destfile=...\\foo\\target\\coverage-reports\\jacoco-ut.exec -XX:MaxPermSize=512m
...
[INFO] --- jacoco-maven-plugin:0.7.0.201403182114:report (jacoco-site) @ foo ---
[INFO] Analyzed bundle 'Foo' with 59 classes`

因此,执行jacoco插件,创建一个surefire.argLine属性,弹出插件的argLine使用surefire.argLine属性和本地MaxPermSize参数,并按预期生成一个target\code-coverage\jacoc-ut-exec文件。

但是,如果我不使用CodeCoverage配置文件,则会出现一个错误,因为${surefire.argLine}属性(在foo/pom.xml中使用)不是由jacoco插件创建的,并且没有在任何地方定义:

代码语言:javascript
运行
复制
[foo] $ mvn clean install -X
...
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator -->
[DEBUG]   (s) argLine = ${surefire.argLine} -XX:MaxPermSize=512m
...
Error: Could not find or load main class ${surefire.argLine}`

Sinec没有调用jacoco插件,也没有创建surefire.argLine属性,因此出现了错误。

因此,我返回到parent/pom.xml并创建这个属性,没有初始值:

parent/pom.xml

代码语言:javascript
运行
复制
<properties>
  <surefire.argLine></surefire.argLine>
</properties>

现在,当我在不使用CodeCoverage配置文件的情况下构建foo模块时,不会出现错误:

代码语言:javascript
运行
复制
[foo] $ mvn clean install -X
...
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator -->
[DEBUG]   (s) argLine =  -XX:MaxPermSize=512m
...
[INFO] BUILD SUCCESS`

弹火as行现在是正确的(使用空的surefire.argLine属性),并且没有target\code-coverage目录,正如预期的那样。

现在我回到生成代码度量,使用CodeCoverage配置文件:

代码语言:javascript
运行
复制
[foo] $ mvn clean install -X -PCodeCoverage
...
[INFO] --- jacoco-maven-plugin:0.7.0.201403182114:prepare-agent (jacoco-initialize) @ foo ---
[INFO] surefire.argLine set to -javaagent:...\\org.jacoco.agent\\0.7.0.201403182114\\org.jacoco.agent-0.7.0.201403182114-runtime.jar=destfile=...\\foo\\target\\coverage-reports\\jacoco-ut.exec
...
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-surefire-plugin:2.13:test' with basic configurator -->
[DEBUG]   (s) argLine =  -XX:MaxPermSize=512m
...
[INFO] --- jacoco-maven-plugin:0.7.0.201403182114:report (jacoco-site) @ foo ---
[INFO] Skipping JaCoCo execution due to missing execution data file:...\foo\target\coverage-reports\jacoco-ut.exec

在这里可以观察到,surefire.argLine插件被调用并设置了surefire.argLine属性,但是在parent/pom.xml文件中定义了空值的surefire.argLine属性实际上是用来为强制插件创建and行的。

因此,当我使用jacoco-ut.exec配置文件时,没有CodeCoverage文件,也没有CodeCoverage目录。

我不知道我在这里做错了什么。我正在声明一个argLine属性,正如jacoco文档所建议的那样,并且每当一个尽责插件需要指定额外的参数时,我都会使用它。Stack溢出上的其他答案建议创建一个与jacoco argLine属性同名的属性,以便在没有调用jacoco时处理这种情况。

有什么建议吗?

编辑

可能有一种解决方案是在surefire.argLine配置文件中显式声明CodeCoverage属性,并忘记使用CodeCoverage插件的argLine

代码语言:javascript
运行
复制
<profile>
  <id>CodeCoverage</id>
  <properties>
    <surefire.argLine>-javaagent:${jacoco.agent.jar}=destfile=${jacoco.report.path}</surefire.argLine>
  </properties>
  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>jacoco-initialize</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
            <!-- no longer specifying 'argLine' for jacoco plugin ... -->  
          </execution>
        <executions> 
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <!-- ... instead the arg line is configured explicitly for surefire plugin. -->
          <argLine>${surefire.argLine}</argLine>
        </configuration>
      </plugin>
    </plugins>
  </plugin>
</build>

这将创建surefire.argLine属性,以使用jacoco插件所需的java代理,并将强制插件配置为将该属性用于其JVM。jacoco插件现在将创建一个argLine属性,但这将被忽略。这不是一个优雅的解决方案(因为我是在假设jacoco插件是如何工作的,这在将来的版本中可能会发生变化)。

编辑

还必须设置jacoco.agent.jar属性,方法是指向其在本地存储库中的位置(不确定这是否健壮),或者使用依赖插件将jacoco代理jar复制到本地构建目录:

代码语言:javascript
运行
复制
<profile>
  <id>CodeCoverage</id>
  <properties>
    <jacoco.agent.jar>${project.build.directory}/jacoco-agent.jar</jacoco.agent.jar>
    ...
  </project>
  <build>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>download-jacoco-agent</id>
            <phase>process-test-resources</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <artifactItems>
                <artifactItem>
                  <groupId>org.jacoco</groupId>
                  <artifactId>org.jacoco.agent</artifactId>
                  <version>${jacoco.version}</version>
                  <classifier>runtime</classifier>
                  <outputDirectory>${project.build.directory}</outputDirectory>
                  <destFileName>jacoco-agent.jar</destFileName>
                </artifactItem>
              </artifactItems>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>

编辑

不确定是否使用依赖插件是正确的方法,或者指向本地存储库中的jacoco代理工件:

代码语言:javascript
运行
复制
<profile>
  <id>CodeCoverage</id>
  <properties>
    <jacoco.agent.jar>${settings.localRepository}/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar</jacoco.agent.jar>
  </properties>
  ...
</profile>

这很简单,不需要将工件复制到本地构建目录,但是很脆弱:存储库布局的更改会破坏这一点。

1

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2014-09-10 20:59:09

由于jacoco-maven-plugin:prepare-agent目标在maven-surefire-plugin之前执行,所以尝试将${argLine}变量添加到maven-surefire-plugin设置的argLine值中。

示例:

代码语言:javascript
运行
复制
<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.12.1</version>
  <configuration>
    <argLine>-server -ea -XX:MaxPermSize=256m -Xmx4g -XX:-UseSplitVerifier ${argLine}</argLine>
  </configuration>
</plugin>

我也遇到了同样的问题,这个解决方案也适用于我,不需要重新配置POM的其他部分。

票数 42
EN

Stack Overflow用户

发布于 2015-02-24 12:25:38

试着使用

代码语言:javascript
运行
复制
@{argLine}

而不是

代码语言:javascript
运行
复制
${argLine}

(或者在您的例子中是surefire.argLine )

它允许强制读取由其他插件修改的属性,而不是读取由Maven本身替换的属性。然后,可以在Maven属性中将argLine参数设置为空:

代码语言:javascript
运行
复制
<properties>
    <argLine></argLine>
</properties>

现在不会引起任何问题。这里有更多信息:如何使用argLine中其他插件设置的属性?

票数 53
EN

Stack Overflow用户

发布于 2015-06-02 14:56:37

如果您的项目已经使用argLine来配置照射表-maven- plugin,那么要确保argLine定义为属性,而不是插件配置的一部分。例如:

代码语言:javascript
运行
复制
  <properties>
    <argLine>-your -extra -arguments</argLine>
  </properties>
  ...
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <!-- Do not define argLine here! -->
    </configuration>
  </plugin>

结果覆盖信息在执行期间收集,并在进程终止时默认写入文件。

为我工作过。请参阅:http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23190107

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档