Maven JaCoCo plugin error
Asked Answered
G

5

24

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?

Grundy answered 4/9, 2012 at 18:46 Comment(0)
I
32

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

Impenetrable answered 17/9, 2012 at 12:28 Comment(5)
adding the <argLine>${argLine}</argLine> worked for me. Just make sure to add it to the build plugin and not to the report plugin (like what I tried first). Thanks.Atonal
Thank a lot How to bring it to site, currently its separate siteForeleg
Thanks for this. I guess one has to be careful when overriding the default configuration of a maven plugin.Bonne
To clarify, one can combine his own argLine contents with jacoco's arguments. E.g. <argLine>-XX:MaxPermSize=128M ${argLine}</argLine>. When tests are run without jacoco, undefined ${argLine} will cause an error, unless this default is added to pom.xml: <properties><argLine></argLine></properties>.Icterus
This does not seem to work for tycho-surefire-plugin. "Error: Could not find or load main class ${argLine}" is output. Anybody used worked this out successfully for Tycho?Borreri
B
21

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

Brutal answered 30/4, 2015 at 18:31 Comment(1)
You can append to the arguments being passed in surefire by using @{argLine}. This will retain the arguments surefire wants and pass the ones that Jacoco wants too. See also: https://mcmap.net/q/125316/-getting-quot-skipping-jacoco-execution-due-to-missing-execution-data-file-quot-upon-executing-jacocoGranddaddy
S
11

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>
Sellma answered 29/8, 2014 at 15:18 Comment(1)
Thank you! That last bit about the test profile was what I was looking for.Gros
V
2

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

Valerievalerio answered 31/10, 2018 at 7:31 Comment(0)
K
0

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
Kelsi answered 5/9, 2012 at 9:13 Comment(4)
Thanks for your response, which I didn't see until today. I tried your configuration, with the exception of the <configuration><skip>${skipTests}</skip></configuration>, but your configuration doesn't solve the problem. Do you have any other ideas?Grundy
You right. I just copied from my project (parent pom). Tests are skipped for some modules. I use jenkins with sonar (and jacoco). There you do not need run jacoco manually.Kelsi
My plugin in the pom.xml file is inside of a profile. I have two profiles: one that executes two JUnit Tests (that are disabled by default), and one that contains the JaCoCo plugin. When I type 'mvn -P test,jacoco install' where "test" and "jacoco" are the two profile names. The tests definitely run, but JaCoCo doesn't produce any .exec files. Any ideas? Also, my project has multiple modules, but the JUnit tests are run from only two of them. The Eclipse JaCoCo plugin obtains coverage data for all modules. Would the Maven Jacoco plugin also obtain coverage data for all modules?Grundy
Maven jacoco plugin (emma,cobertura) creates report for current module only. mvn help:describe -Dplugin=org.jacoco:jacoco-maven-plugin -Ddetail - describes append parameter. Check your execution with mvn help plugin. mvn -P test,jacoco help:active-profilesKelsi

© 2022 - 2024 — McMap. All rights reserved.