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

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

问题描述

我正在将maven与 jacoco 插件一起使用以生成代码覆盖率指标.我在使用 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\\\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属性, surefire 插件的argLine使用surefire.argLine属性,而本地MaxPermSize参数,并按预期生成一个target\code-coverage\jacoc-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 target\code-coverage\jacoc-ut-exec file is generated, as expected.

但是,如果我不使用 CodeCoverage 配置文件,则会收到错误消息,因为 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}`

没有调用 jacoco 插件的Sinec,没有创建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属性),并且没有target\code-coverage目录,符合预期.

The surefire argline is now correct (using the empty surefire.argLine property) and there is no target\code-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\target\coverage-reports\jacoco-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文件,也没有target\code-coverage目录.

As a result, there is no jacoco-ut.exec file, and no target\code-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属性,而不必使用 jacoco 插件的argLine:

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属性,方法是指向其在本地存储库中的位置(不确定它是否可靠),或者使用 dependency 插件复制 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 agent工件:

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-set设置的argLine值中surefire插件.

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天全站免登陆