JaCoCo uses the Surefire argLine
to add a javaagent which collects the coverage data.
If you customize the argLine
i.e. for increasing the heap size (-Xmx1536m
) you must
preserve the possibility for JaCoCo to still add its javaagent.
This is best done by @argLine
(see explanation below).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>@{argLine} ${surefireArgLine} -Xmx1536m</argLine>
</configuration>
</plugin>
In the following I walk you through the possible variations and traps of them.
Simple usage
When you start using Jacoco it’s easy, you add the plugin configuration like below,
start your test with mvn test
and you have a file with execution data (target/jacoco.exec
).
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
Adjust Surefire argLine in pom.xml
Next you maybe want to give your tests more heap size with -Xmx1536m
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>-Xmx1536m</argLine>
</configuration>
</plugin>
The heap size is increased, but jacoco.exec
is missing and hence JaCoCo was not executed.
Now we need to understand how the JaCoCo Maven plug-in works. JaCoCo uses a javaagent to collect the execution data,
for that the prepare-agent goal sets the argLine
property which is then consumed by
surefire:test argLine.
You can see this in the log:
[INFO] --- jacoco-maven-plugin:0.8.5:prepare-agent (default-prepare-agent) @ jacoco-argLine ---
[INFO] argLine set to -javaagent:<...>org.jacoco.agent-0.8.5-runtime.jar=destfile=<...>target\\jacoco.exec
But, if the argLine
is already defined in the configuration, surefire will not read the property and therefore the javaagent will
not be added.
This can be fixed by adding a placeholder in the configuration which then can again consume the property.
<configuration>
<argLine>${argLine} -Xmx1536m</argLine>
</configuration>
Now the argLine
set by prepare-agent is consumed by ${argLine}
and jacoco.exec
is written again.
Adjust Surefire argLine with user property
Sometimes you don’t want to hardcode everything in the pom.xml
and use user properties. E. g.
mvn clean test -DargLine="-Dfoo=bar"
. With the configuration above jacoco.exec
again is not written as
${argLine}
is replaced by -Dfoo=bar
and no placeholder is left to consume the jacoco argLine.
Since Version 2.17 Surefire provides a solution for this: late property evaluation.
With @{argLine}
evaluation is done from surefire itself. So you could use:
<configuration>
<argLine>@{argLine} ${argLine} -Xmx1536m</argLine>
</configuration>
Although two argLine variables are confusing it works when called with a argLine user property (-DargLine="-Dfoo=bar"
),
but it fails without due to the duplicate javaagent:
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was cmd.exe /X /C ""<...>\bin\java" -javaagent:<...> -javaagent:<...> -Xmx1536m -jar <...>\surefirebooter17379281364314664758.jar <...>
Solution
As already @{argLine}
consumes the javaagent you can freely rename the other variable as you wish.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<argLine>@{argLine} ${surefireArgLine} -Xmx1536m</argLine>
</configuration>
</plugin>
This can be called successfully with mvn clean test -DsurefireArgLine="-Dfoo=bar"
.
But without it will fail due to the not replaced surefireArgLine variable.
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was cmd.exe /X /C ""<...>\bin\java" -javaagent:<...> ${surefireArgLine} -Xmx1536m -jar <...>\surefirebooter17379281364314664758.jar <...>
When you add and empty surefireArgLine
property you are prepared for both cases:
<properties>
<surefireArgLine></surefireArgLine>
</properties>
Twitter
Email