Jacoco report imported but coverage not displayed in SonarCloud

I have a maven multi-module java project for which I can’t get the coverage to show on SonarCloud. I followed the instructions here, which suggest adding a project submodule to aggregate the coverage report of other submodules.
My report aggregation maven submodule is called: coverage-report-aggregator
In the parent POM,
I defined sonar.coverage.jacoco.xmlReportPaths property:

<sonar.coverage.jacoco.xmlReportPaths>
      ${project.basedir}/coverage-report-aggregator/target/site/jacoco-aggregate/jacoco.xml
</sonar.coverage.jacoco.xmlReportPaths>

and defined the jacoco maven plugin:

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

In the report aggregator submodule coverage-report-aggregator, I added the other submodules as dependencies and added the Jacoco plugin setup:

...
  <dependencies>
    <dependency>
      <groupId>com.myorg</groupId>
      <artifactId>module-one</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>com.myorg</groupId>
      <artifactId>module-two</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>
...

  <build>
    <plugins>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>report-aggregate</id>
            <phase>verify</phase>
            <goals>
              <goal>report-aggregate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

When I run mvn install locally against the parent project, the reports get aggregated as expected under: <parent-project>/coverage-report-aggregator/target/site. Opening the local index.html file shows that both submodules (module-one and module-two) have test coverage as expected.
However after Sonar analysis is run from CI/CD (see Drone setup further below), there is no coverage shown on SonarCloud:
image

CI/CD logs show that Jacoco report XML file was imported by sonar:

[INFO] 12:03:37.443 Importing 1 report(s). Turn your logs in debug mode in order to see the exhaustive list.
[DEBUG] 12:03:37.443 Reading report '/drone/src/coverage-report-aggregator/target/site/jacoco-aggregate/jacoco.xml'
[INFO] 12:03:37.461 Sensor JaCoCo XML Report Importer [jacoco] (done) | time=18ms

I’ve also checked that the aggregate XML report file existed on the CI/CD server, and it size matched the size of the equivalent one I got generated on my local machine:

+ ls -l ./coverage-report-aggregator/target/site/jacoco-aggregate/jacoco.xml
-rw-r--r--. 1 root root 196570 Nov  2 12:03 ./coverage-report-aggregator/target/site/jacoco-aggregate/jacoco.xml

I hope someone can help me get to the root cause of this problem.

Thanks in advance.

More details about the setup

  • ALM used: GitHub
  • CI system used: Drone
  • Scanner command used:
steps:
- name: build
  image: maven:3.8-openjdk-17
  commands:
  - mvn clean install

- name: sonar
  image: maven:3.8-openjdk-17
  depends_on:
  - build
  environment:
    SONAR_HOST:
      from_secret: sonar_cloud_host
    SONAR_TOKEN:
      from_secret: sonar_cloud_token
  commands:
  - mvn -X sonar:sonar 
    -Dsonar.host.url=$${SONAR_HOST} 
    -Dsonar.login=$${SONAR_TOKEN}
    -Dsonar.organization=myOrganisation
    -Dsonar.projectKey=parent-project
    -Dsonar.branch.name=$DRONE_BRANCH
    -Dsonar.projectName=parent-project
  when:
    event:
      exclude:
      - pull_request
  • Languages of the repository: Java

P.S.
I’ve tried the solution mentioned by this post but it didn’t work. It sounds a bit irrational anyway.

Hey @taomoh

Welcome to our community!

This may be a dumb question (or just ignorance of how things work with Drone), but my first reading of your pipeline implies to me that your mvn clean install and mvn sonar:sonar are running in two separate docker images.

Is there any chance you have accidentally checked your coverage report into your repo, and that’s actually what the scanner is trying to read?

Hey @Colin. Thank you for the warm welcome :slight_smile:

The two Drone steps use separate docker images indeed but somehow they share the volume. I can say so because I injected an ls command in the sonar step of Drone pipeline and could see that the coverage report was present:

+ ls -l ./coverage-report-aggregator/target/site/jacoco-aggregate/jacoco.xml
-rw-r--r--. 1 root root 196570 Nov  2 12:03 ./coverage-report-aggregator/target/site/jacoco-aggregate/jacoco.xml

The good news is that I finally got this to work by:

  • Creating a brand new sonar project, as I suspected the original one got somehow corrupted.

  • Adding a git fetch step ahead of the build (see code snippet below), as sonar was showing this warning Could not find ref 'main' in refs/heads, refs/remotes/upstream or refs/remotes/origin. You may see unexpected issues and changes. Please make sure to fetch this ref before pull request analysis. This is probably a Drone issue and not a Sonar one

...
- name: fetch
  image: alpine/git
  commands:
    - "git fetch origin +refs/heads/main:"

- name: build
  image: maven:3.8-openjdk-17
  depends_on:
    - fetch
  commands:
  - mvn clean install

- name: sonar
  image: maven:3.8-openjdk-17
  depends_on:
  - build
  environment:
....
  • Moved the declaration of sonar.coverage.jacoco.xmlReportPaths property from the parent POM to the report-aggregator submodule’s POM
<sonar.coverage.jacoco.xmlReportPaths>
      ${project.basedir}/target/site/jacoco-aggregate/jacoco.xml
</sonar.coverage.jacoco.xmlReportPaths>
  • Adding a report goal execution under jacoco-maven-plugin in the parent POM. This is to cause the XML report coverage to be generated for all submodules
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.8</version>
                <executions>
                    <execution>
                        <id>prepare-agent</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>report</id>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
1 Like

By the way, the report aggregator additional submodule is completely unnecessary: sonarcloud analysis works fine without it