Multi-Modules Apache Maven Sonarqube Scanner
Author : Hamza EL YAAQOUBI
Introduction
In my current mission, I was faced with a fairly well-known but little documented problem, It’s the aggregation of the overall test coverage of an application built with Apache Maven.
That’s why I thought of writing this article in order to share and help the community ;)
Installations
In this article, I will use Docker to install the LTS version of SonarQube (v8.2.0), so I suppose that you’re familiar with Docker and its commands.
- Docker
To check if docker is installed on your machine, type the following command :
hamza@hamza-perso:~$ docker -v
The result should be something like this :
If docker is not installed, please refer to the official web site.
- SonarQube LTS
Firstly, start with search SonarQube docker image
hamza@hamza-perso:~$ docker search sonarqube
Secondly install SonarQube docker image
hamza@hamza-perso:~$ docker pull sonarqube
Finally run SonarQube docker container
hamza@hamza-perso:~$ docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube
And visit the local server on http://localhost:9000 :
Project
Architecture
The architecture of the project looks like :
This project contains essentially 3 sub modules. As example, we have a sub domain domain
and web
and coverage
.
The first two modules contain java classes and units tests.
The sub module web
depends on sub module domain
, that’s mean we have a dependency of domain
in web
.
The third sub module coverage
allows us to generate aggregate coverage report (xml format in my case) needed by SonarQube.
It imports all of sub modules on which we want coverage to be imported.
Configuration
In the parent pom.xml file, I will just add jacoco-maven-plugin and maven-surefire-plugin as plugins management because they will be used by all of sub modules.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surfire.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Then, I will configure a default enabled profile so as to collect coverage data from all of sub modules :
<profiles>
<profile>
<id>coverage-init</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<sonar.host.url>http://localhost:9000/</sonar.host.url>
<sonar.login>03a85d7c38de33297e41b57deb50573abe0086b6</sonar.login>
</properties>
</profile>
</profiles>
As you can see, I configured two properties sonar.host.url and sonar.login to avoid using them on command line.
In the next step, we will configure pom.xml file of coverage
sub module to generate the target report by collecting data from sub modules using report-aggregate goal.
This goal will create a file named jacoco.xml located at coverage/target/site/jacoco-aggregate
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>report</id>
<goals>
<goal>report-aggregate</goal>
</goals>
<phase>verify</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
Finally, we have to import the generated report in every sub modules on which this coverage should be imported.
According to the official documentation and analysis coverage documentation, the property sonar.jacoco.reportPaths is deprecated since 8.0 version and replaced by sonar.coverage.jacoco.xmlReportPaths
To accomplish this import, we have just to set sonar.coverage.jacoco.xmlReportPaths in every sub modules as follows :
<properties>
<sonar.coverage.jacoco.xmlReportPaths>${project.basedir}/../coverage/target/site/jacoco-aggregate/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
</properties>
Results
Once the configuration is done, you can type the following command to generate report and publish the result on Sonarqube server :
hamza@hamza-perso:~$ mvn install sonar:sonar
As you can see, after connecting to the SonarQube (login: admin, password: admin), you can check the result of the coverage :
The all of source code is located here.
That’s all !
Don’t hesitate to send me your feedback :)
Thank you.