I have a multi maven java project and I succeeded to create jacoco.exec file per module.
This is the relevant part in the parent pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>group.id</groupId>
<artifactId>java-parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Java Tools</name>
<modules>
<module>module1</module>
<module>module2</module>
<module>module3</module>
</modules>
<prerequisites>
<maven>3.3.9</maven>
</prerequisites>
<properties>
<!-- JaCoCo thresholds -->
<jacoco.percentage.instruction>0.800</jacoco.percentage.instruction>
<!-- Sonar -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPaths>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPaths>
<sonar.exclusions>
**/JavaProjectApiXSAModule.java,
**/JavaProjectApiCPModule.java
</sonar.exclusions>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.core</artifactId>
<version>0.7.9</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<!-- http://mvnrepository.com/artifact/org.apache.maven.plugins/maven-surefire-plugin -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/Test*Unit*</include>
</includes>
<reuseForks>false</reuseForks>
<argLine>-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${project.build.directory} @{argLine}</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<destFile>${sonar.jacoco.reportPaths}</destFile>
<append>true</append>
<excludes>
<exclude>com.sun.*</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>jacoco-check</id>
<phase>test</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco.percentage.instruction}</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
As you can see:
1. I configured jacoco.percentage.instruction which I override in each sub module to adjust the coverage threshold accordingly.
2. Until I added the following configuration:
<destFile>${sonar.jacoco.reportPaths}</destFile>
<append>true</append>
I was able to make the build fail in case the coverage did not meet the defined threshold.
3. I added this destFile and append=true configuration as suggested here: https://stackoverflow.com/questions/13031219/how-to-configure-multi-module-maven-sonar-jacoco-to-give-merged-coverage-rep?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
I wanted sonar to consume the jacoco.exec files from each module.
I tried before to use sonar.reportPaths and to point to the different modules but that didn't work out and I had to find a way to show % in our sonar and this is the only way I found.
Is there a way to "enjoy from both worlds"? i.e. fail the build when coverage threshold is not met per module and to aggregate 1 jacoco.exec for sonar?
Thank you very much in advance!
Vered
Thank you very much for your help!
I posted a question to sonar ops colleagues in our organization and they are trying to help with the first thing you suggested Marc, thanks.
In the meantime I thing merge would be a good workaround..
I added this execution at the end of all the executions:
<execution>
<id>merge-results</id>
<phase>verify</phase>
<goals>
<goal>merge</goal>
</goals>
<configuration>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>*.exec</include>
</includes>
</fileSet>
</fileSets>
<destFile>${project.build.directory}/jacoco.exe</destFile>
</configuration>
</execution>
</executions>
However I just get another jacoco.exec file in each sub module target folder.
When I configured destFile to be:
<destFile>${project.basedir}/../target/jacoco.exe</destFile>
because I want to merge them in the parent target folder... I get jacoco.exec file in target folder of the parent but I don't think it is a correct merged result as its size is 9k only.... it cannot be that is contains all the jacocos - I have ten of them and each one is at least 400k...
I read few time the documentation but I'm a maven beginner so I'm probably missing something here?
Evgeny - did you mean to say that the "check" for coverage threshold should not be affected? In practice, I see it did with the above configuration...it did not failed the build when I changed to higher threshold...:(
Evgeny - did you mean to say that the "check" for coverage threshold should not be affected? In practice, I see it did with the above configuration...it did not failed the build when I changed to higher threshold...:(
Thank you so much for you responsiveness and help!
Evgeny, I used your hint and configured dataFile the same as destFile path and it worked! The build now fails when coverage is not met + I have 1 jacoco file using the append that will be used by our sonar.
The configuration will look like this:
<dataFile>${sonar.jacoco.reportPaths}</dataFile>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco.percentage.lines}</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
We are a big organization and this way I configured jacoco and sonar will be used by other teams when I give my green light.
As you are the experts, I would appreciate if you let me know in case you recognize issues with it.
Thank you so much! I'm so happy to see it all plays together:)
Thank you very much for your feedback!
You are right, I will take it under consideration also.
Best Regards,
Vered