Jacoco scanner maps coverage info to wrong file in a multi-module maven project

I am trying to import a jacoco report via jenkins for a multi module maven project, but getting some errors on the commandline when the jacoco-scanner is trying to import the jacoco.xml file.

The project is creating multiple artefacts (both jar’s and war’s) and is using an overlay.

parent (pom)
- ProjectA (jar)
- ProjectB (war)
- ProjectC (war)
- reports (pom)

According to some guides I set up a reports project so I can aggregate the different reports for ProjectA, ProjectB and ProjectC.
The reports project has all these projects as dependencies and creates an aggregated report. The parent project contains the ‘sonar.coverage.jacoco.xmlReportPaths’ property so all projects point to the same jacoco file.

Each project is represented as a group inside the file, e.g.
The File mentioned in the StackTrace below exists twice in the report in two different groups (for ProjectA and ProjectC).
In ProjectA the File has 391 lines, in ProjectC its overriden and only has 389 lines. These information are correctly represented in the jacoco.xml file.

When the jacoco-scanner is now trying to import the report - when analysing/processing ProjectC - it looks like the coverage information is mapped to the wrong file.

The import in sonarqube seems uneffected by this, at least I could not (easily) identifiy that something is wrong with the coverage report, but I guess some parts might be missing through to these error(s).

I would like to get some verification if this is a known issue.

Java 17
SonarQube (community edition) 9.5
Jacoco maven plugin version 0.8.7
Jacoco Scanner 1.1.1.1157


Importing 1 report(s). Turn your logs in debug mode in order to see the exhaustive list.
Reading report '[ommited]/../reports/target/site/jacoco-aggregate/jacoco.xml'

Cannot import coverage information for file 'ProjectC/src/main/java/[ommited]/File.java', coverage data is invalid. Error: {}
java.lang.IllegalStateException: Line 391 is out of range in the file ProjectC/src/main/java/[ommited]/File.java (lines: 390)
    at org.sonar.api.utils.Preconditions.checkState(Preconditions.java:61)
    at org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage.validateLine(DefaultCoverage.java:81)
    at org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage.lineHits(DefaultCoverage.java:69)
    at org.sonar.plugins.jacoco.ReportImporter.importCoverage(ReportImporter.java:45)
    at org.sonar.plugins.jacoco.JacocoSensor.importReport(JacocoSensor.java:79)
    at org.sonar.plugins.jacoco.JacocoSensor.importReports(JacocoSensor.java:62)
    at org.sonar.plugins.jacoco.JacocoSensor.execute(JacocoSensor.java:47)
    at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
    at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:81)
    at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
    at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
    at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:392)
    at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:388)
    at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:385)
    at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:357)
    at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
    at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
    at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:135)
    at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
    at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
    at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72)
    at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66)
    at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
    at jdk.proxy3/jdk.proxy3.$Proxy24.execute(Unknown Source)
    at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
    at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
    at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:65)
    at org.sonarsource.scanner.maven.SonarQubeMojo.execute(SonarQubeMojo.java:108)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:192)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)

Hello @simonk,

Sorry for such a late reply. About your problem, as far as I understood correctly you have 2 files with the same name and package in 2 different modules. Am I right?

Could you please also check if your HTML report of JaCoCo tool shows results correctly? Does it show covered/not-covered lines highlighted in appropriate colors in HTML?

As far as I remember if you have 2 files with the same package and the same name in the aggregated report, neither JaCoCo nor SonarQube can locate the source files correctly. This doesn’t affect the numbers but will affect the source code mapping.

Looking forward to your answers.

Regards,
Margarita