Unable to run JUnit 4 tests successfully when using Jacoco

301 Views Asked by At

We have recently upgraded our project to JDK 11 and have noticed that Surefire no longer generates the .exec file for Jacoco. Casting around for a solution, we modifier our Maven POM file to pick up the arg from Jacoco and give it to Surefire, as shown below:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.4</version>
    <executions>
        <execution>
            <id>jacoco-initialize</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
            <!-- gets the aguament from here -->
            <configuration>
                <propertyName>surefireArgLine</propertyName>
            </configuration>
        </execution>
        <execution>
            <id>post-unit-test</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
            <configuration>
                <outputDirectory>./codeCoverage/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.7</version>
    <configuration>
        <!-- and uses it here -->
        <argLine>
            ${surefireArgLine}
            -Xmx1024m
            -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.9/jmockit-1.9.jar
            --add-reads java.base=java.logging
            --add-reads java.xml=java.logging
        </argLine>
    </configuration>
</plugin>

Now, although the .exec is produced for Jacoco, the unit tests fail with the following:

java.lang.ArrayIndexOutOfBoundsException: Index 110 out of bounds for length 110
      at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
      at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
      at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
      at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
      at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
      at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)

We've tried upgarding various parts (JMockit to 1.23, Surefire to 2.22.2), but to no avail: they produce variations on the above.

Has anyone come across a similar situation and have any useful suggestions? It all worked fine under JDK 1.8

Update: and surefireArgLine gets set to

[INFO] --- jacoco-maven-plugin:0.8.3:prepare-agent (coverage-initialize) ---
[INFO] surefireArgLine set to -javaagent:.m2/repository/org/jacoco/org.jacoco.agent/0.8.3/org.jacoco.agent-0.8.3-runtime.jar=destfile=/target/jacoco.exec
1

There are 1 best solutions below

0
Aaron Aardvark On

And I figured out a solution. Firstly, as above, add the parameter to allow Jacoco to add an argument to the argLine of Surefire. Then make sure this is the line after the javaagent parameter for JMockit (otherwise, this blocks the JMockit line and you get an error saying that JMockit requires JDB 6+):

<argLine>
      -Xmx1024m
      -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.9/jmockit-1.9.jar
      ${surefireArgLine}
      --add-reads java.base=java.logging
      --add-reads java.xml=java.logging
</argLine>

Finally, make sure that Jacoco is version 0.8.3, as there is a problem with 0.8.4 (called the "condy" problem) See GitHub issue comment