无法在 maven 中同时使用 jacoco JVM args 和 surefire JVM args [英] Cannot use jacoco JVM args and surefire JVM args together in maven

查看:35
本文介绍了无法在 maven 中同时使用 jacoco JVM args 和 surefire JVM args的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using maven with the jacoco plugin to generate code coverage metrics. I am having some difficulty in configuring the surefire plugin with the java options required by the jacoco plugin. I've seen some answers about this already on Stack Overflow but something is not working for me.

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

I have a multi-module project, and one of my modules configures the surefire plugin as follows:

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>

这按预期工作.

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

Now I want to incorporate jacoco to get code coverage metrics, so I added a CodeCoverage profile that handles all the jacoco configuration:

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>

这里看到,如果指定了 CodeCoverage 配置文件,则 jacoco 插件被配置为使用 surefire.argLine 属性,该属性用于为 surefire 插件配置 argLine.

It is seen here that if the CodeCoverage profile is specified, then the jacoco plugin is configured to use the surefire.argLine property, and that property is used to configure the argLine for the surefire plugin.

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

I then updated the pom.xml file for the foo module to use the surefire.argLine property generated by the jacoco plugin:

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>

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

This approach is specified in the jacoco plugin documentation (see [1]).

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

When I build the foo module with the CodeCoverage profile, I see the following:

[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\	arget\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 插件使用 surefire.argLine 属性和本地 MaxPermSize 参数,并且一个 targetcode-coveragejacoc-ut-exec 文件是按预期生成.

So the jacoco plugin is executed, a surefire.argLine property is created, the argLine for the surefire plugin uses the surefire.argLine property and the local MaxPermSize argument, and a targetcode-coveragejacoc-ut-exec file is generated, as expected.

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

However, if I do not use the CodeCoverage profile, then I get an error, because the ${surefire.argLine} property (used in foo/pom.xml) is not created by the jacoco plugin, and is not defined anywhere:

[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 属性,因此出现错误.

Sinec the jacoco plugin was not invoked, there's no surefire.argLine property created, hence the error.

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

So, I go back to the parent/pom.xml and create this property, with no initial value:

parent/pom.xml:

<properties>
  <surefire.argLine></surefire.argLine>
</properties>

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

Now when I build the foo module without using the CodeCoverage profile, I get no errors:

[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`

surefire argline 现在是正确的(使用空的 surefire.argLine 属性)并且没有 targetcode-coverage 目录,正如预期的那样.

The surefire argline is now correct (using the empty surefire.argLine property) and there is no targetcode-coverage directory, as expected.

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

So now I go back to generating code metrics, using the CodeCoverage profile:

[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	argetcoverage-reportsjacoco-ut.exec

这里可以观察到 jacoco 插件被调用并设置了 surefire.argLine 属性,但是 surefire.argLine 属性与parent/pom.xml 文件中定义的空值实际上用于为 surefire 插件创建 argline.

It can be observed here that the jacoco plugin is invoked and sets the surefire.argLine property, but the surefire.argLine property with the empty value defined in the parent/pom.xml file is actually used to create the argline for the surefire plugin.

结果,当我使用 CodeCoverage 时,没有 jacoco-ut.exec 文件,也没有 targetcode-coverage 目录em> 个人资料.

As a result, there is no jacoco-ut.exec file, and no targetcode-coverage directory, when I use the CodeCoverage profile.

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

I'm not sure what I am doing wrong here. I'm declaring an argLine property as suggested by the jacoco documentation, and using it whenever a surefire plugin needs to specify additional argument. Other answers on Stack Overflow suggest creating a property with the same name as the jacoco argLine property to handle the case when jacoco is not invoked.

有什么建议吗?

编辑

也许一种解决方案是在 CodeCoverage 配置文件中显式声明 surefire.argLine 属性,而忘记使用 argLineem>jacoco 插件:

Maybe one solution is to explicitly declare the surefire.argLine property in the CodeCoverage profile, and forget about using the argLine of the jacoco plugin:

<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 代理,并配置 surefire 插件使用其 JVM 参数的该属性.jacoco 插件现在将创建一个 argLine 属性,但这将被忽略.这不是一个优雅的解决方案(因为我对 jacoco 插件的工作方式做了假设,这可能会在未来版本中改变).

This will create the surefire.argLine property to use the java agent required by the jacoco plugin, and configure the surefire plugin to use that property for its JVM args. The jacoco plugin will now create a argLine property, but this will be ignored. It's not an elegant solution (since I'm making assumptions about how the jacoco plugin works, and this may change in a future version).

编辑

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

The jacoco.agent.jar property must also be set, by pointing to its location in the local repository (not sure if this is robust) or by using the dependency plugin to copy the jacoco agent jar to the local build directory:

<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>

编辑

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

Not sure if using the dependency plugin is the right approach, or pointing to the jacoco agent artifact in the local repository:

<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>

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

This is simpler, and does not require copying an artifact to the local build directory, but is fragile: changes in the repository layout will break this.

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

推荐答案

由于 jacoco-maven-plugin:prepare-agent 目标在 maven-surefire-plugin 之前执行,请尝试添加 ${argLine} 变量转换为 maven-surefire-plugin 设置的 argLine 值.

Since the jacoco-maven-plugin:prepare-agent goal executes before the maven-surefire-plugin, try adding the ${argLine} variable into the argLine value set by the maven-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>

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

I had the same problem and this solution worked for me, without any need to reconfigure other sections of the POM.

这篇关于无法在 maven 中同时使用 jacoco JVM args 和 surefire JVM args的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆