Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quarkus JaCoCo - Generated jacoco.xml is not parseable anymore by the sonar-maven-plugin #37544

Closed
bchetty opened this issue Dec 5, 2023 · 15 comments · Fixed by #37570
Closed
Labels
area/maven kind/bug Something isn't working
Milestone

Comments

@bchetty
Copy link

bchetty commented Dec 5, 2023

Describe the bug

Since Quarkus-3.6.0, the generated jacoco.xml is not "Parseable" by the sonar-maven-plugin. Below is the StackTrace:

Error: Coverage report '/__w/<GITHUB-WORKSPACE>/<GIT-REPO>/target/jacoco-report/jacoco.xml' could not be read/imported. Error: {} java.lang.IllegalStateException: Failed to parse JaCoCo XML report: /__w/<GITHUB-WORKSPACE>/<GIT-REPO>/target/jacoco-report/jacoco.xml at org.snar.plugins.jacoco.XmlReportParser.parse(XmlReportParser.java:108) at org.sonar.plugins.jacoco.JacocoSensor.importReport(JacocoSensor.java:72) at org.sonar.plugins.jacoco.JacocoSensor.importReports(JacocoSensor.java:64) at org.sonar.plugins.jacoco.JacocoSensor.execute(JacocoSensor.java:55) at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64) at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88) at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61) at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79) at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61) at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82) 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:403) at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:399) at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:368) 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:137) 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:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60) at jdk.proxy4/jdk.proxy4.$Proxy27.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:64) at org.sonarsource.scanner.maven.SonarQubeMojo.execute(SonarQubeMojo.java:108) at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:1***) at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2(MojoExecutor.java:328) at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute(MojoExecutor.java:316) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:174) at org.apache.maven.lifecycle.internal.MojoExecutor.access$000(MojoExecutor.java:75) at org.apache.maven.lifecycle.internal.MojoExecutor$1.run(MojoExecutor.java:162) at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute(DefaultMojosExecutionStrategy.java:39) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:159) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:105) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:73) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:53) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:***8) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:***1) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:173) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:101) at org.apache.maven.cli.MavenCli.execute(MavenCli.java:906) at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:283) at org.apache.maven.cli.MavenCli.main(MavenCli.java:206) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) 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) Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,8202] Message: Element type "counter" must be followed by either attribute specifications, ">" or "/>". at java.xml/com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:652) at org.sonar.plugins.jacoco.XmlReportParser.parse(XmlReportParser.java:61) ... 59 common frames omitted

Expected behavior

The generated jacoco.xml should be "Parseable" by the sonar-plugin for publishing the report.

Actual behavior

Since Quarkus-3.6.0, the generated jacoco.xml is not "Parseable" by the sonar-maven-plugin.

How to Reproduce?

Reproducer:

Steps to reproduce the bug:

  1. Create a single module maven project with some basic tests
  2. Configure "org.sonarsource.scanner.maven:sonar-maven-plugin" to the latest version: 3.10.0.2594
  3. Configure quarkus-jacoco as per the Quarkus documentation here: https://quarkus.io/guides/tests-with-coverage
  4. Run the "mvn clean install && mvn sonar:sonar" commands

Output of uname -a or ver

No response

Output of java -version

17

Quarkus version or git rev

3.6.0

Build tool (ie. output of mvnw --version or gradlew --version)

maven 3.8.1

Additional information

Sonar maven plugin ( org.sonarsource.scanner.maven:sonar-maven-plugin) version: 3.10.0.2594

@bchetty bchetty added the kind/bug Something isn't working label Dec 5, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Dec 5, 2023

/cc @quarkusio/devtools (maven)

@famod
Copy link
Member

famod commented Dec 5, 2023

Do some of your tests use @TestProfile or @QuarkusTestResource? If yes you might have the same issue as #37496.

@bchetty
Copy link
Author

bchetty commented Dec 6, 2023

@testprofile

Yes, the application sources use both the annotations ( @TestProfile && @QuarkusTestResource )

@bchetty
Copy link
Author

bchetty commented Dec 6, 2023

And BTW, with this new version of Quarkus, the quarkus-jacoco generated report is also incorrect (with 0% coverage) for a maven-multi-module setup ( maven-surefire & maven-failsafe are configured as per the Quarkus documentation: https://quarkus.io/guides/tests-with-coverage )

@edeandrea
Copy link
Contributor

edeandrea commented Dec 6, 2023

I actually ran into this when I recently introduced sonar scanning into the Quarkus superheroes sample application. Those projects integrate all kinds of tests:

  • Tests using @QuarkusTest
  • Tests without using @QuarkusTest
  • Integration tests using @QuarkusIntegrationTest
  • Tests using @TestProfile and @QuarkusTestResource

Out of the box I did see the error that @bchetty describes. I don't know if it would have worked in a Quarkus version before 3.6.0 as I only did all this on 3.6.0. This gives me a full representation of the coverage of a Quarkus application. I've even combined it with Quarkus Quinoa for an app that has both a backend and a React front-end. The backend & frontend coverage reports are combined into a single report (see https://sonarcloud.io/project/overview?id=quarkusio-quarkus-super-heroes_ui-super-heroes for the output and https://github.com/quarkusio/quarkus-super-heroes/blob/main/.github/workflows/sonar-scan.yml#L67-L88 for the scanning setup while also adding https://github.com/edeandrea/quarkus-super-heroes/blob/02ffe115b817fef0859852565222b86eb551d971/ui-super-heroes/src/main/webui/package.json#L19).

How much of this is required vs gaps in the documentation I'm not sure, but as of right now with Quarkus 3.6.0 (& 3.6.1) this works and sonar understands it.

Including coverage for both unit & integration tests

When you run the build to include coverage for both unit & integration tests you have to build with the -Dquarkus.package.write-transformed-bytecode-to-build-output=true flag, as mentioned in the documentation.

I also had to adjust the sonar.coverage.jacoco.xmlReportPaths and sonar.junit.reportPaths keys when performing the sonar scan: -Dsonar.coverage.jacoco.xmlReportPaths=target/jacoco-report/jacoco.xml,target/jacoco-it-report/jacoco.xml -Dsonar.junit.reportPaths=target/surefire-reports

https://github.com/quarkusio/quarkus-super-heroes/blob/main/.github/workflows/sonar-scan.yml is the GitHub action which performs the scan (in case you're interested).

https://sonarcloud.io/organizations/quarkusio-quarkus-super-heroes is the project dashboard on SonarCloud.

pom.xml additions to fix the issue

I was able to fix everything by adding this code snippet to the pom.xml, along with the quarkus-jacoco extension & the above-mentioned updated flags to the sonar scan.

      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.11</version>
        <executions>
          <execution>
            <id>default-prepare-agent</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
            <configuration>
              <exclClassLoaders>*QuarkusClassLoader</exclClassLoaders>
              <destFile>${project.build.directory}/jacoco-quarkus.exec</destFile>
              <append>true</append>
            </configuration>
          </execution>
          <execution>
            <id>unit-report</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>report</goal>
            </goals>
            <configuration>
              <dataFile>${project.build.directory}/jacoco-quarkus.exec</dataFile>
              <outputDirectory>${project.build.directory}/jacoco-report</outputDirectory>
            </configuration>
          </execution>
          <execution>
            <id>default-prepare-agent-integration</id>
            <goals>
              <goal>prepare-agent-integration</goal>
            </goals>
            <configuration>
              <destFile>${project.build.directory}/jacoco-quarkus-it.exec</destFile>
              <append>true</append>
            </configuration>
          </execution>
          <execution>
            <id>integration-report</id>
            <phase>post-integration-test</phase>
            <goals>
              <goal>report</goal>
            </goals>
            <configuration>
              <dataFile>${project.build.directory}/jacoco-quarkus-it.exec</dataFile>
              <outputDirectory>${project.build.directory}/jacoco-it-report</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>

@amkac
Copy link

amkac commented Dec 7, 2023

Same issue for my side with quarkus 3.6.0

@amkac
Copy link

amkac commented Dec 8, 2023

The problem should be fixed in this PR #37570

@famod
Copy link
Member

famod commented Dec 10, 2023

The problem should be fixed in this PR #37570

That will be part of 3.6.2.
Please report back whether it truly fixes the sonar issue, thanks!

@amkac
Copy link

amkac commented Dec 11, 2023

The problem should be fixed in this PR #37570

That will be part of 3.6.2. Please report back whether it truly fixes the sonar issue, thanks!

Yes of course, when will the version 3.6.2 be released ?

@famod
Copy link
Member

famod commented Dec 11, 2023

3.6.2 should be available on Wednesday, maybe even already tomorrow evening.
But that's all up to @gsmet!

@amkac
Copy link

amkac commented Dec 13, 2023

@famod I confirm the problem is fixed in the version 3.6.3

@famod
Copy link
Member

famod commented Dec 13, 2023

Nice, thanks for reporting back @amkac!

@famod famod closed this as completed Dec 13, 2023
@famod famod modified the milestones: 3.6.3, 3.6.2 Dec 13, 2023
@famod
Copy link
Member

famod commented Dec 13, 2023

PS: Actually fixed in 3.6.2, but I'd strongly suggest to avoid 3.6.2 because of a config regression.

@bchetty
Copy link
Author

bchetty commented Dec 13, 2023

Dependabot (on Github Enterprise) is not yet picking up the latest version...I will test it from my side and update the ticket. Thanks :)

@bchetty
Copy link
Author

bchetty commented Dec 14, 2023

I just tested that and it's working. Thank you for the fix! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/maven kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants