Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get sonar to process jacoco exec files for a multi-module maven project

I'm trying to generate unit test code coverage data for sonar for a multi-module maven project, and not getting correct results.

The project structure is similar to the following:

  • project
    • parentPom
    • moduleA
    • moduleB
      • module B1
      • module B2
    • module C

I am using the jacoco maven plugin to generate jacoco.exec files, and the sonar maven plugin to analyse the code (including the jacoco.exec files).

These files are generated during the process-tests phase, as follows:

<properties>
  <jacoco.report.path>${project.build.directory}/jacoco.exec</jacoco.report.path>
  <sonar.jacoco.reportPath>${jacoco.report.path}</sonar.jacoco.reportPath>
</properties>

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.7.4.201502262128</version>
  <executions>
    <execution>
      <id>default-prepare-agent</id>
      <phase>process-test-classes</phase>
      <goals>
        <goal>prepare-agent</goal>
      </goals>
      <configuration>
        <destFile>${jacoco.report.path}</destFile>
      </configuration>
    </execution>
  </executions>
</plugin>

When I run mvn clean install I can see that there is a jacoco.exec file created for each module:

$ find . -name '*.exec'
./moduleA/target/jacoco.exec
./moduleB/moduleB1/target/jacoco.exec
./moduleB/moduleB2/target/jacoco.exec
./moduleC/target/jacoco.exec

When I run mvn sonar:sonar I see that the Jacoco sensor runs for all modules, but only seems to work with the first module. Subsequent modules show Coverage information was not collected:

[INFO] [17:13:58.333] Sensor JaCoCoSensor
[INFO] [17:13:58.350] Analysing moduleA\target\jacoco.exec
[INFO] [17:13:58.374] No information about coverage per test.
[INFO] [17:13:58.374] Sensor JaCoCoSensor (done) | time=41ms
...
[INFO] [17:14:02.202] Sensor JaCoCoSensor
[INFO] [17:14:02.261] Analysing moduleB\moduleB1\target\jacoco.exec
[WARN] [17:14:02.334] Coverage information was not collected. Perhaps you forget to include debug information into compiled classes?
[INFO] [17:14:02.334] Sensor JaCoCoSensor (done) | time=132ms
...

I'm not sure why there's no coverage information in the second and subsequent modules, since maven-compiler-plugin includes debug information by default, and to be safe I also ran mvn clean install -Dmaven.compiler.debug=true but got the same results.

As a consequence of this, when I inspect the project in the sonar server it shows code coverage just for the first module: moduleA. No code coverage information for the other modules is present.

Apparently the solution here is to generate only a single jacoco.exec file, so that when the jacoco-maven-plugin executes it appends the result for each module to that file, so that sonar can work its magic correctly.

Accordingly, I modified my parentPom/pom.xml file as follows:

<properties>
  <!-- single jacoco.exec file relative to root directory of the project -->
  <jacoco.report.path>${session.executionRootDirectory}/code-coverage/jacoco.exec</jacoco.report.path>
  <sonar.jacoco.reportPath>${jacoco.report.path}</sonar.jacoco.reportPath>
</properties>

<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.7.4.201502262128</version>
  <executions>
    <execution>
      <id>default-prepare-agent</id>
      <phase>process-test-classes</phase>
      <goals>
        <goal>prepare-agent</goal>
      </goals>
      <configuration>
        <destFile>${jacoco.report.path}</destFile>
        <append>true</append> <!-- now appending to single jacoco.exec file -->
      </configuration>
    </execution>
  </executions>
</plugin>

This means that after unit tests have run, the jacaco agent is invoked Now when I run mvn clean install I see only one jacoco.exec file:

$ find . -name '*.exec'
./code-coverage/target/jacoco.exec

But when I run mvn sonar:sonar the JaCoCoSensor does not seem to be invoked and the project on the sonar server has no code coverage at all.

What am I doing wrong here? How do I get sonar to analyse code coverage for all modules in my maven project?

Do I need to modify the maven-surefire-plugin in some way?

I am using SonarQube 5.1, JDK 1.8, jacoco-maven-plugin 0.7.4.201502262128

like image 610
John Q Citizen Avatar asked Jul 15 '15 07:07

John Q Citizen


1 Answers

JaCoCo sensor will only load coverage for the classes you covered in your module.

This means that if for some reason the jacoco.exec in your module B does not contain coverage information about the .class files of this module then it won't load any coverage (even if you covered classes in another module).

like image 87
benzonico Avatar answered Sep 19 '22 21:09

benzonico