22

我在 pom.xml 文件中配置了 Maven JaCoCo 插件,如下所示:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <jacoco.version>0.5.9.201207300726</jacoco.version>
</properties>

<profiles>
    <profile>
        <id>jacoco4</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>${jacoco.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                            <configuration
                            <destfile>${project.build.directory}/target/jacoco.exec</destfile>
                            <datafile>${project.build.directory}/target/jacoco.exec</datafile>
                                <output>file</output>
                                <append>true</append>
                            </configuration>
                        </execution>
                        <execution>
                            <id>report</id>
                            <phase>prepare-package</phase>
                            <goals>
                                <goal>report</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

我正在使用 Windows 7 和 apache-maven-3.0.4 插件。当我mvn -P jacoco4 install从 cygwin 终端或命令提示符终端键入 时,Maven 会下载并运行 JaCoCo 插件,但jacoco.exec似乎没有创建该文件。以下是错误消息:

[ERROR] Unable to read execution data file C:\Users\brownru\workspace64new\vps9\vps-fileserver\target\jacoco.exec: C:\Users\brownru\workspace64new\vps9\vps-fileserver\target\jacoco.exec (The system cannot find the file specified)
java.io.FileNotFoundException: C:\Users\brownru\workspace64new\vps9\vps-fileserver\target\jacoco.exec (The system cannot find the file specified)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:120)
        at org.jacoco.maven.ReportMojo.loadExecutionData(ReportMojo.java:251)
        at org.jacoco.maven.ReportMojo.executeReport(ReportMojo.java:228)
        at org.jacoco.maven.ReportMojo.execute(ReportMojo.java:217)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)

无论我是否在插件的配置中包含destfileand说明符,都会出现此错误消息:datafile

<destfile>${project.build.directory}/target/jacoco.exec</destfile>
<datafile>${project.build.directory}/target/jacoco.exec</datafile>

有人可以告诉我我做错了什么吗?

4

5 回答 5

29

我对 jacoco 和 maven 也有同样的麻烦。它与覆盖surefire配置的父pom有关。在这种情况下,该插件没有使用定义代理的参数(用于 jvm 参数)。

解决方案是将“argLine”配置元素放回去

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
   <argLine>${argLine}</argLine>
  </configuration>
 </plugin>

完整的插件配置看起来像

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <skip>true</skip>
  </configuration>
  <executions>
    <execution>
      <id>unit-test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
      <configuration>
        <skip>${maven.test.skip}</skip>
        <argLine>${argLine}</argLine>
        <excludes>
          <exclude>**/*IntegrationTest.java</exclude>
        </excludes>
      </configuration>
    </execution>
    <execution>
      <id>integration-test</id>
      <phase>integration-test</phase>
      <goals>
        <goal>test</goal>
      </goals>
      <configuration>
        <skip>${skipITs}</skip>
        <argLine>${argLine}</argLine>
        <includes>
          <include>**/*IntegrationTest.java</include>
        </includes>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.5.10.201208310627</version>
    <configuration>
        <skip>${maven.test.skip}</skip>
        <destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
        <dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
        <output>file</output>
        <append>true</append>
    </configuration>
    <executions>
        <execution>
            <id>jacoco-initialize</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>jacoco-site</id>
            <phase>verify</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

希望它会有用

于 2012-09-17T12:28:53.360 回答
20

好的,我想我知道发生了什么。

默认情况下,jacoco 插件在测试阶段之前“运行”(通常它在初始化prepare-agent生命周期阶段运行目标),当它运行时,它只是将一个名为“argLine”的 maven 属性设置为类似-javaagent=jacoco.jar

前任:

[INFO] argLine 设置为 -javaagent:/usernamed/.m2/repository/org/jacoco/org.jacoco.agent/ 0.5.6.201201232323/org.jacoco.agent-0.5.6.201201232323-runtime.jar=destfile=/path/到/目标/jacoco.exec

默认情况下,maven-surefire-plugin 基本上将这个属性(如果它设置为任何东西)“预先设置”到其分叉的 java 测试进程中,所以他们得到了货物。前任:java ${argLine ends up here}> -jar /xxx/surefirebooter3741906822495182152.jar

通常(没有 jacoco),如果您还想在该 argLine 中添加您自己的其他内容(例如,等等-Xmx1G),您只需在surefire 配置中设置它,例如

 <build>
   <plugins>
    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
            <argLine>-Xmx1G</argLine>
          </configuration>
     </plugin>

但是,如果您使用的是 jacoco,则不能通过设置全局属性来按常规方式进行操作,而是采用这种方式(这是 pom 的根全局属性):

  <properties>
    <argLine>-Xmx1G</argLine>
  </properties>

如果您确实设置了,<configuration><argLine>那么它基本上会覆盖系统属性,因此 jacoco 参数不会传递给子进程。所以这就是你使用属性方式的原因。如果您指定一个属性argLine,那么 jacoco 只会将其参数添加到您指定的任何内容中,然后 surefire 将使用它。

但是,如果您的父 pom已经将插件设置<configuration><argLine>为某些东西怎么办?或者如果你自己设置它?它基本上会使用该值而不是 jacoco 设置的属性(您已指定手动覆盖)。

如果您指定<configuration><argLine>自己,则可以将该 argLine 更改为一个属性(见上文),然后删除<configuration><argLine>它,它应该可以工作。如果您无法控制父级,并且父级为 argline 指定了某些内容,那么您将需要走这<configuration><argLine>${argLine} -Xmx1G</argLine>条路。这是为了指示它忽略父级将此值设置为的任何值,并改用 argLine(jacoco 为您设置的那个)。(我不清楚是否有一种简单的方法可以“添加”到父 pom 对该值的值,如果有人知道如何在此处随意评论)。

但是,如果 jacoco 没有针对某个目标或某个配置文件运行呢?然后变量${argLine}永远不会被设置,你可能会遇到这样的错误:

目标 org.apache.maven.plugins:maven-surefire-plugin:2.14:test 的执行默认测试失败:分叉的虚拟机在没有正确告别的情况下终止。VM 崩溃或 System.exit 调用?[错误] 命令是/bin/sh -c cd ...java '${argLine}' ...

事实证明,jacoco 在运行时只“添加”到名为 argLine 的属性。因此,您可以安全地将 a 添加<properties><argLine></argLine></properties>到您的 pom 中(除非您已经在父 pom 中设置了该设置,否则您无需添加任何内容)。如果曾经调用过 jacoco,它会添加它。如果不是,它被设置为一个空字符串,这没关系。也不清楚是否有一种方法可以“添加”到属性的父级值,所以它要么继承它,如果你知道它存在,或者将它指定为空。

所以,最后对我来说,因为我的上游(无法访问)父 pom 声明它就像

<configuration><argList>${argList}</argList></configuration>

我被迫基本上遵循这条路线,因为它已经设置在(我无法控制的)父 pom 中,因此:

<configuration><argList>${argList} -Xmx1G</argList></configuration>

注意,如果你的 pom 中有这个,Intellij 会抱怨并且“不添加任何设置”到你的单元测试中:

<configuration><argLine>${argLine} -DcustomOption=X...</argLine>

但根本不要声明名为 argLine 的属性(即使它在命令行 mvn 上工作得很好)。修复/解决方法:声明一个空的 'argLine' 全局属性,和/或只是将您-DcustomOption=X移至属性声明,见上文。如果你“只”在属性声明中设置它,那么为了让 IntelliJ 拿起它,你还需要 <configuration><argLine>${argLine}</argLine>...:|

不幸的是,即使这还不够,它还支持声纳,尽管它与 IntelliJ + maven 一起使用。不知道为什么。改变了我解析时间的方式,所以不必弄乱这些区域(即代码中的“正确”)。

于 2015-04-30T18:31:38.917 回答
10

我也遇到了这个问题:JaCoCo 没有生成“jacoco.exec”输出文件,这意味着没有发生代码覆盖率分析。

在我的情况下,这也是由于在 Maven Surefire 插件中使用自定义 argLine 覆盖了 JaCoCo Maven 插件 argLine,导致 JaCoCo 无法执行。

为了解决这个问题,我使用 JaCoCo 可选参数“propertyName”将其 argLine 导出到 Maven 属性,并将其包含在 Surefire argLine 中:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <configuration>
        <propertyName>jacoco.agent.argLine</propertyName>
    </configuration>
    ...             
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.10</version>
    <configuration>
        <argLine>-XX:-UseSplitVerifier ${jacoco.agent.argLine}</argLine>
    </configuration>
</plugin>

但是,当在 Netbeans 中运行单个测试时,这会导致问题。因为在这种情况下没有执行 JaCoCo 插件,所以“jacoco.agent.argLine”变量没有初始化,并且 Surefire 在运行任何测试之前失败。

在 pom 中添加一个空白属性“jacoco.agent.argLine”解决了运行单个测试时的问题,但这也阻止了 JaCoCo 在执行时导出其 argLine,从而有效地禁用了 JaCoCo。

我使用的解决方案的最后一部分是添加一个创建空白属性的配置文件,并且仅在指定单个测试时激活:

<profiles>
    <profile>
        <activation>                
            <property>
                <name>test</name>      
            </property>
        </activation>
        <properties>
            <jacoco.agent.argLine></jacoco.agent.argLine>
        </properties>
    </profile>
</profiles>
于 2014-08-29T15:18:29.390 回答
1

我遇到了同样的问题并通过使用以下命令代替 jacoco:report -

mvn -X org.jacoco:jacoco-maven-plugin:report 

参考 -如何从命令行配置 JaCoCo maven 插件

于 2018-10-31T07:31:28.373 回答
0

我使用配置:

    <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>${jacoco.version}</version>
            <configuration>
                    <skip>${skipTests}</skip>
            </configuration>
            <executions>
                    <execution>
                                <id>jacoco-initialize</id>
                                <phase>initialize</phase>
                                <goals>
                                    <goal>prepare-agent</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>jacoco-site</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>report</goal>
                                </goals>
                            </execution>
            </executions>
        </plugin>

更新: 声纳生成的配置(sonar-pom.xml):

<plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.12</version>
        <executions>
          <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
              <goal>test</goal>
            </goals>
            <configuration>
              <excludedGroups>server,ignore,integration</excludedGroups>
            </configuration>
          </execution>
        </executions>
        <configuration>
          <excludedGroups>server,ignore,integration</excludedGroups>
          <argLine>-javaagent:/tmp/jacocoagent3671192291664069011.jar=destfile=target/jacoco.exec,excludes=*_javassist_*</argLine>
          <testFailureIgnore>true</testFailureIgnore>
        </configuration>
      </plugin>

一个问题 - 如何为每个构建定义“jacocoagent3671192291664069011.jar”。它应该在:

$M2_HOME/repository/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar
于 2012-09-05T09:13:21.900 回答