Empty jacoco xml file is still counted in by Sonar Scanner

In a Kotlin Multiproject setup we have gradle/jacoco/sonarqube working fine.
However, I tried to exclude some projects as they contain only generated code and started by excluding them from jacoco by configuring:

jacocoTestReport {
        dependsOn test
        reports {
            xml.required = true
            csv.required = false
            html.required = true
        afterEvaluate {
            classDirectories.setFrom(files(classDirectories.files.collect {
                fileTree(dir: it, exclude: [

Which leads to Jacoco xml and html files containing no further info.
But in Sonarqube it showed 0.0% and was still counted in to my overall test coverage.

I then found that I can exclude code for sonar by adding:

sonar {
    properties {
        property "sonar.coverage.exclusions", "src/main/**"

to the build.gradle files.

I’ve read through some articles here to find if this is intended behaviour but could not really find out.

So mabye someone here can answer this?
Shouldn’t empty (i.e. only xml header but no content for classes) jacoco xml files lead to excluded coverage info in Sonarqube? Just like it does when I use sonar.coverage.exclusions?


No. In fact we worked hard for just the opposite.


1 Like

Thank you Ann, that does explain the behaviour.

The other side effect is that if you’ve explicitly configured your coverage engine to ignore certain parts of your code base, well… SonarQube is going to automatically re-incorporate them, so you’ll have to configure the exclusions again on the SonarQube side, but that should be a one-time operation.

I still think the behaviour is kind of unexpected. The coverage engine should be the leading source of truth (and I think there should always be only one source of truth - at least as a default). So if I configure the coverage engine to exclude generated code then I don’t want SonarQube to include it again.
And furthermore our projects are constantly changing (refactorings, etc), so I also have to remember to adjust the coverage engine. And now I have to always remember to do it at two places (Jacoco - in my case) and SonarQube.

It would be cool, if this behaviour was configurable. Maybe a switch to tell SonarQube to reflect exactly what the coverage engine says.

Just my humble opinion. Thanks for the answer!


1 Like