Maven JaCoCo plugin error

喜你入骨 提交于 2019-12-17 18:09:26

问题


I have configured the Maven JaCoCo plugin as follows in my pom.xml file:

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

I'm using Windows 7 and the apache-maven-3.0.4 plugin. When I type mvn -P jacoco4 install, either from a cygwin terminal or from a command prompt terminal, Maven downloads and runs the JaCoCo plugin, but then the jacoco.exec file doesn't appear to have been created. Below is the error message:

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

This error message appears whether or not I include the destfile and datafile specifiers in the configuration of the plugin:

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

Can someone please tell me what I'm doing wrong?


回答1:


I had the same trouble with jacoco and maven. It was related to a parent pom overwriting the configuration of surefire. In this case, that plugin didn't used the argument (for jvm argument) defining the agent.

The solution was to put the "argLine" configuration element back

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

Full plugin conf looks like

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

Hope it'll be usefull




回答2:


OK I think I figured out what is going on.

By default, the jacoco plugin "runs" before the test phase (typically it runs the prepare-agent goal during the initialize lifecycle phase), and when it runs, it just sets a maven property called "argLine" to something like -javaagent=jacoco.jar

ex:

[INFO] argLine set to -javaagent:/usernamed/.m2/repository/org/jacoco/org.jacoco.agent/ 0.5.6.201201232323/org.jacoco.agent-0.5.6.201201232323-runtime.jar=destfile=/path/to/target/jacoco.exec

By default, maven-surefire-plugin basically "prepends" this property (if it's set to anything) to its forked java test processes, so they get the goods. Ex: java ${argLine ends up here}> -jar /xxx/surefirebooter3741906822495182152.jar

Typically (without jacoco), if you want to also add something else of your own to that argLine (for instance, -Xmx1G or the like), you just set it in the surefire configuration, like

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

However, if you're using jacoco, you can't do it the normal way you do it by setting a global property, this way instead (this is the pom's root global properties):

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

If you do set the <configuration><argLine> then it basically overrides the system property, so jacoco arguments aren't passed down to the child process. So that's why you use the property way instead. If you specify a property argLine then jacoco will just add its parameters to whatever you specify, then surefire will use it.

However, what if your parent pom has already set the plugin's <configuration><argLine> to something? Or if you yourself are setting it? It will basically use that value instead of the property that jacoco is setting (you've specified a manual override).

If you're specifying <configuration><argLine> yourself, you can change that argLine into a property (see above), and remove the <configuration><argLine> and it should work. If you can't control the parent, and the parent specifies something for argline, then you'll need to go the the <configuration><argLine>${argLine} -Xmx1G</argLine> route. This is to instruct it to ignore whatever the parent set this value to, and use argLine instead (the one jacoco sets for you). (It's unclear to me if there's an easy way to "add" to the value the parent pom has for this value, if anybody knows how feel free to comment here).

But what if jacoco doesn't run for some target, or some profile? Then the variable ${argLine} never gets set, and you can run into an error like this:

Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.14:test failed: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ? [ERROR] Command was/bin/sh -c cd ...java '${argLine}' ...

Well it turns out that jacoco only "adds" to the property named argLine, when it runs. So you can safely add a <properties><argLine></argLine></properties> to your pom (unless you already have that set in the parent pom, then you don't need to add anything). If jacoco is ever invoked, it adds to it. If not, it's set to an empty string, which is OK. It's also unclear if there's a way to "add" to the parent's value for a property, so it's either inherit it, if you know it exists, or specify it as empty.

So, in the end for me, since my upstream (inaccessible) parent pom declared it like

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

I was forced to basically follow that route, since it was set already in an (out of my control) parent pom, thusly:

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

NB that Intellij will complain and "not add any settings" to your unit test if you have this in your pom:

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

but don't declare a property named argLine at all (even though it works on the command line mvn just fine). Fix/work around: declare an empty 'argLine' global property, and/or just move your -DcustomOption=X to the property declaration instead, see above. If you "only" set it in the property declaration then for IntelliJ to pick it up you'll also need <configuration><argLine>${argLine}</argLine>... :|

Unfortunately even this wasn't enough, it hosed sonar, though worked with IntelliJ + maven. Not sure why. Changed the way I parsed times instead, so didn't have to mess with the zones (i.e. "got them right" in the code).




回答3:


I also came across this problem: JaCoCo doesn't produce a 'jacoco.exec' output file, meaning that no code coverage analysis occurs.

In my case it was also due to using a custom argLine in the Maven Surefire Plugin which overrided the JaCoCo Maven Plugin argLine, causing JaCoCo not to be executed.

To fix this I used the JaCoCo optional parameter "propertyName" to export its argLine to a Maven property and included that in the 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>

However this caused a problem when individual tests were run in Netbeans. Because the JaCoCo plugin was not executed in this scenario the "jacoco.agent.argLine" variable wasn't initialised and Surefire failed before running any tests.

Adding a blank property "jacoco.agent.argLine" to the pom solved the issue when running single tests, but this also stopped JaCoCo from exporting its argLine when it was being executed, effectively disabling JaCoCo.

The final part of the solution that I've used was to add a profile which creates the blank property, and activates only when a single test is specified:

<profiles>
    <profile>
        <activation>                
            <property>
                <name>test</name>      
            </property>
        </activation>
        <properties>
            <jacoco.agent.argLine></jacoco.agent.argLine>
        </properties>
    </profile>
</profiles>



回答4:


I faced the same problem and fixed by using below command in place of jacoco:report -

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

Referred - How to configure JaCoCo maven plugin from command line




回答5:


I use configuration:

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

Update: Configuration generated by sonar (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>

One problem - how to define "jacocoagent3671192291664069011.jar" for each build. It should be in:

$M2_HOME/repository/org/jacoco/org.jacoco.agent/${jacoco.version}/org.jacoco.agent-${jacoco.version}-runtime.jar


来源:https://stackoverflow.com/questions/12269558/maven-jacoco-plugin-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!