Sonar JaCoCoSensor ignoring jacoco analysis

Viewed 1684

I have a multi-module maven project that has both in module unit tests and end-to-end service tests (not quite integration tests since they don't actually integrate with anything) where we mock at the boundaries of the particular service being tested. This latter set of tests (using mockmvc to exercise all layers before deployment) generate a jacoco.exec (or jacoco-it.exec depending on the maven configuration I try) that clearly shows that the tests contribute to code coverage. In fact that vast majority of coverage is in this layer (roughly 40% per jacoco).

When I run sonar analysis on the project locally, or via jenkins, I get the following for the top level tests:

[INFO] Sensor JaCoCoSensor [java]

[INFO] Analysing /Users/tokkov/Documents/workspace/platform/customer/assemblies/service/target/jacoco.exec

[WARNING] Coverage information was not collected. Perhaps you forget to include debug information into compiled classes?

[INFO] Sensor JaCoCoSensor [java] (done) | time=164ms

So sonar finds the jacoco analysis. It finds the compiled code (unpacked the jars into the build directory and specified location with sonar.java.binaries), the compiled code does have debug info (verified with javap -l), but it still throws up its hands and moves on.

Any ideas why sonar ignores the jacoco report? Am I missing a configuration somewhere? It happily gobbles up all of the jacoco.exec reports in the other modules, just not this one.

<sonar.java.binaries>${project.build.directory}/class-fix</sonar.java.binaries>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPaths>${project.build.directory}/jacoco.exec</sonar.jacoco.reportPaths>

The versions: Sonarqube v 7.1 (build 11001), JaCoCo maven plugin v 0.8.1

2 Answers

This is configuration in pom.xml that works for me:

    <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
    <sonar.language>java</sonar.language>

and jacoco plugin settings in the same pom.xml:

        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.1</version>
            <configuration>
                <destFile>${sonar.jacoco.reportPath}</destFile>
                <append>true</append>
            </configuration>
            <executions>
                <execution>
                    <id>agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

The issue appears to be with nesting maven modules. The project structure was highly nested in nature, I believe to help mentally reinforce the segregation of the hexagonal architecture they were implementing. This lead to several modules that just contained other modules and the sonar plugin seemed to get lost in how the code was related. Once I removed any non-code containing modules to flatten the folder structure a bit the reporting came through just like it should have.

On a second project I specified the use of a single jacoco.exec file so that jacoco could aggregate it prior to sonar becoming involved. This also addressed the issue and allowed teams to preserve a highly nested maven structure.

In both cases the issue seemed to be that sonar does not handle cross module code references for coverage purposes unless the jacoco results are aggregated prior to sonar analysis.

This is a significant problem with end to end service testing that defeats the benefits of code segregation into discrete modules.

tl;dr Sonar cannot handle multiple levels of nested maven modules. And completely ignored code outside of the module containing tests.

Related