John Q Citizen
John Q Citizen

Reputation: 207

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:

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

Upvotes: 6

Views: 3732

Answers (1)

benzonico
benzonico

Reputation: 10833

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).

Upvotes: 1

Related Questions