不能在maven中使用jacoco JVM args和surefire JVM args

Joh*_*zen 60 maven maven-surefire-plugin jacoco

我正在使用带有jacoco插件的maven 来生成代码覆盖率指标.我有在配置一些困难神火由所需的Java插件的选项jacoco插件.我已经在Stack Overflow上看到了一些关于此问题的答案,但有些东西对我不起作用.

我有一个多模块项目,我的一个模块配置了surefire插件,如下所示:

foo/pom.xml:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>-XX:MaxPermSize=512m</argLine>
    </configuration>
  </plugin>
</plugins>
Run Code Online (Sandbox Code Playgroud)

这按预期工作.

现在我想结合jacoco获取代码覆盖率的指标,所以我加了一个代码覆盖率配置文件,处理所有jacoco配置:

parent/pom.xml:

<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>
Run Code Online (Sandbox Code Playgroud)

它是在这里看到的是,如果代码覆盖率指定配置文件,然后jacoco插件配置为使用surefire.argLine属性,该属性用于配置argLine万无一失插件.

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

foo/pom.xml:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>${surefire.argLine} -XX:MaxPermSize=512m</argLine>
    </configuration>
  </plugin>
</plugins>
Run Code Online (Sandbox Code Playgroud)

这种方法在jacoco插件文档中指定(参见[1]).

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

[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`
Run Code Online (Sandbox Code Playgroud)

所以jacoco执行插件,一个surefire.argLine是创建属性时,argLine神火插件使用的surefire.argLine属性和当地MaxPermSize的说法,并且target\code-coverage\jacoc-ut-exec生成文件,符合市场预期.

但是,如果我不使用CodeCoverage配置文件,那么我会收到错误,因为该${surefire.argLine}属性(用于foo/pom.xml)不是由jacoco插件创建的,并且未在任何地方定义:

[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}`
Run Code Online (Sandbox Code Playgroud)

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

所以,我回到parent/pom.xml并创建此属性,没有初始值:

parent/pom.xml:

<properties>
  <surefire.argLine></surefire.argLine>
</properties>
Run Code Online (Sandbox Code Playgroud)

现在,当我在不使用CodeCoverage配置文件的情况下构建foo模块时,我没有收到任何错误:

[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`
Run Code Online (Sandbox Code Playgroud)

万无一失 argline现在是正确的(使用空surefire.argLine属性)并没有target\code-coverage目录,符合市场预期.

所以现在我回到使用CodeCoverage配置文件生成代码指标:

[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
Run Code Online (Sandbox Code Playgroud)

从中可看出,jacoco插件调用和设置surefire.argLine属性,但surefire.argLine与中定义的空值属性parent/pom.xml的文件实际上是用来创建用于该argline 万无一失插件.

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

我不确定我在这里做错了什么.我声明了一个argLine属性由所建议的jacoco文档,并且只要使用它万无一失插件需要指定额外的参数.Stack Overflow上的其他答案建议创建一个与jacoco argLine属性同名的属性来处理未调用jacoco时的情况.

有什么建议?

编辑

也许一个解决方案是显式声明surefire.argLine的属性代码覆盖率曲线,而忘记使用argLine的的jacoco插件:

<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>
Run Code Online (Sandbox Code Playgroud)

这将创建surefire.argLine财产使用由所需的Java代理jacoco插件,并配置万无一失插件使用该财产的JVM ARGS.该jacoco插件现在将创建一个argLine属性,但是这将被忽略.这不是一个优雅的解决方案(因为我正在假设jacoco插件如何工作,这可能会在未来版本中发生变化).

编辑

jacoco.agent.jar属性也必须设置,通过在本地存储库(不知道这是否是健壮)指向其位置或使用依赖插件的复制jacoco剂罐子到本地build目录:

<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>
Run Code Online (Sandbox Code Playgroud)

编辑

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

<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>
Run Code Online (Sandbox Code Playgroud)

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

[1] http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html

小智 37

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

例:

<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>
Run Code Online (Sandbox Code Playgroud)

我有同样的问题,这个解决方案对我有用,无需重新配置POM的其他部分.


Kas*_*zaq 36

尝试使用

@{argLine}
Run Code Online (Sandbox Code Playgroud)

代替

${argLine}
Run Code Online (Sandbox Code Playgroud)

(或surefire.argLine在您的情况下)

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

<properties>
    <argLine></argLine>
</properties>
Run Code Online (Sandbox Code Playgroud)

现在哪个不会造成任何问题.更多信息:如何使用argLine中其他插件设置的属性?

  • @Gili Per [`maven-surefire-plugin`常见问题解答](http://maven.apache.org/surefire/maven-surefire-plugin/faq.html)链接在答案中:“Maven对`$进行属性替换在任何插件运行之前,`pom.xml` 中的 {...}` 值。因此 Surefire 永远不会在其 `argLine` 属性中看到占位符。自版本 2.17 开始,这些属性使用替代语法,`@{ ...}` 允许在执行插件时延迟替换属性,因此已被其他插件修改的属性将被正确拾取。” (3认同)

小智 18

如果您的项目已经使用argLine配置surefire-maven-plugin,请确保将argLine定义为属性,而不是作为插件配置的一部分.例如:

  <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>
Run Code Online (Sandbox Code Playgroud)

生成的覆盖信息在执行期间收集,并且在进程终止时默认写入文件.

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


Fai*_*roz 11

尝试在属性部分添加argLine属性(如下面的代码所示),而不是在maven-sure-fire插件的配置部分添加它.Jacoco maven插件只会附加到此,事情将按预期工作.

<properties>
  <argLine>-XX:MaxPermSize=512m</argLine>
</properties>
Run Code Online (Sandbox Code Playgroud)

请参阅https://docs.sonarqube.org/display/PLUG/Usage+of+JaCoCo+with+Java+Plugin


Ard*_*sco 5

我的解决方案是使用多个配置文件。

第一个配置文件设置surefire.argLine和 的空白值failsafe.argLine,并且默认情况下处于活动状态。

<profile>
    <id>not-sonar</id>
    <properties>
        <surefire.argLine/>
        <failsafe.argLine/>
    </properties>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>
Run Code Online (Sandbox Code Playgroud)

第二个配置文件具有 jacoco 插件配置,默认情况下处于非活动状态。

<profile>
<id>sonar</id>
<activation>
    <activeByDefault>false</activeByDefault>
</activation>
<build>
    <plugins>
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco-maven-plugin-version}</version>
            <executions>
                <execution>
                    <id>default-prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                    <configuration>
                        <propertyName>surefire.argLine</propertyName>
                    </configuration>
                </execution>
                <execution>
                    <id>default-prepare-agent-integration</id>
                    <goals>
                        <goal>prepare-agent-integration</goal>
                    </goals>
                    <configuration>
                        <propertyName>failsafe.argLine</propertyName>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
</profile>
Run Code Online (Sandbox Code Playgroud)

当您激活声纳配置文件时,非声纳配置文件将自动关闭。

这应该比使用其他插件为您完成工作更优雅一些。您现在可以${surefire.argLine}在 argLine 中使用该变量,它将始终存在并在运行构建时进行设置。

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
      <argLine>${surefire.argLine} -XX:MaxPermSize=512m</argLine>
    </configuration>
  </plugin>
Run Code Online (Sandbox Code Playgroud)

如果由于 ${surefire.argLine} 没有值而仍然遇到问题,您还可以设置一个虚拟属性,如下所示:

<profile>
    <id>not-sonar</id>
    <properties>
        <surefire.argLine>-DdummyProperty=notUsed</surefire.argLine>
        <failsafe.argLine>-DdummyProperty=notUsed</failsafe.argLine>
    </properties>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>
Run Code Online (Sandbox Code Playgroud)