You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SonarQube扫描Scala多模块项目代码覆盖率显示为0的问题排查

Scala多模块项目SonarQube覆盖率显示0的问题排查与修复

问题背景

扫描Scala多模块项目时,本地Jacoco模块报告显示语句覆盖率36.07%、分支覆盖率6.25%,且已成功生成jacoco.exec和jacoco.xml报告,但SonarQube控制台出现Zero Coverage Sensor日志,Sonar仪表盘覆盖率仍为0。

现有pom.xml关键配置片段

<!-- Sonar -->
<sonar.version>3.7.0.1746</sonar.version>
<jacoco.version>0.7.9</jacoco.version>
<sonar.projectName>abc</sonar.projectName>
<sonar.projectDescription>abc:xyz</sonar.projectDescription>
<sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
<sonar.jacoco.reportPaths>jacoco.exec</sonar.jacoco.reportPaths>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.language>scala</sonar.language>
<sonar.sources>src/main/scala</sonar.sources>
<sonar.binaries>target/classes</sonar.binaries>
<sonar.inclusions>**/*.scala</sonar.inclusions>
<sonar.exclusions>src/test/**</sonar.exclusions>
<scoverage.plugin.version>1.4.1</scoverage.plugin.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.scala.coveragePlugin>jacoco</sonar.scala.coveragePlugin>
<sonar.scala.coverage.reportPath>target/scoverage.xml</sonar.scala.coverage.reportPath>
<sonar.coverage.jacoco.xmlReportPaths>${project.build.directory}/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
<junit.version>4.11</junit.version>
<!-- Sonar -->

<!-- 部分资源配置 -->
<configuration>
    <outputDirectory>${project.build.outputDirectory}</outputDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>jacoco.exec</include>
            </includes>
        </resource>
    </resources>
</configuration>

<!-- Build插件配置 -->
<build>
    <resources>
        <resource>
            <directory>/src/main/resources</directory>
        </resource>
        <resource>
            <directory>/src/test/resources</directory>
        </resource>
    </resources>
    <plugins>
        <!-- maven-resources-plugin 配置 -->
        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>${maven-resource-plugin.version}</version>
            <configuration>
                <includeEmptyDirs>true</includeEmptyDirs>
            </configuration>
            <executions>
                <execution>
                    <id>copy-resource</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
                        <resources>
                            <resource>
                                <directory>src/main/resources</directory>
                                <includes>
                                    <include>jacoco.exec</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
                <execution>
                    <id>copy-test-resource</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>testResources</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.testOutputDirectory}</outputDirectory>
                        <resources>
                            <resource>
                                <directory>src/test/resources</directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- maven-surefire-plugin 配置 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.16</version>
            <configuration>
                <argLine>-XX:-UseSplitVerifier -Djava.net.preferIPv4Stack=true -Xms256m
                    -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m
                </argLine>
                <redirectTestOutputToFile>true</redirectTestOutputToFile>
            </configuration>
        </plugin>
        <!-- jacoco-maven-plugin 配置 -->
        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.6</version>
            <configuration>
                <destFile>${sonar.jacoco.reportPath}</destFile>
                <append>true</append>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
                <execution>
                    <id>post-unit-test</id>
                    <phase>test</phase>
                    <goals>
                        <goal>report-aggregate</goal>
                    </goals>
                    <configuration>
                        <dataFile>jacoco.exec</dataFile>
                        <outputEncoding>UTF-8</outputEncoding>
                        <outputDirectory>${project.build.directory}</outputDirectory>
                        <systemPropertyVariables>
                            <jacoco-agent.destfile>jacoco.exec</jacoco-agent.destfile>
                        </systemPropertyVariables>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

问题排查与修复步骤

1. 统一Jacoco版本,解决版本冲突

当前pom中jacoco.version配置为0.7.9,但jacoco-maven-plugin使用的是0.8.6,版本不一致会导致报告解析异常。统一版本:

<jacoco.version>0.8.6</jacoco.version>

同时确保插件引用该版本:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>${jacoco.version}</version>
    <!-- 其余配置不变 -->
</plugin>

2. 修正SonarQube覆盖率报告路径配置

  • 移除过时的sonar.jacoco.reportPaths(该属性已废弃,官方推荐使用sonar.coverage.jacoco.xmlReportPaths)
  • 多模块项目需指定聚合后的xml报告路径,父pom中配置:
<sonar.coverage.jacoco.xmlReportPaths>${project.basedir}/target/site/jacoco-aggregate/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>

3. 移除冲突的Scala覆盖率配置

同时配置Jacoco和Scoverage会导致Sonar解析混淆,移除Scoverage相关配置:

<!-- 移除以下两行 -->
<scoverage.plugin.version>1.4.1</scoverage.plugin.version>
<sonar.scala.coverage.reportPath>target/scoverage.xml</sonar.scala.coverage.reportPath>

4. 确保Surefire插件继承Jacoco的Agent参数

Jacoco的prepare-agent会自动在argLine中添加Agent参数,硬编码argLine会覆盖该配置,导致无法生成有效覆盖率数据。修改Surefire配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
        <argLine>@{argLine} -XX:-UseSplitVerifier -Djava.net.preferIPv4Stack=true -Xms256m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m</argLine>
        <redirectTestOutputToFile>true</redirectTestOutputToFile>
    </configuration>
</plugin>

5. 调整Jacoco插件的多模块执行配置

  • 父模块执行report-aggregate聚合所有子模块的覆盖率数据,子模块仅执行prepare-agent和report生成单模块报告
  • 父pom的Jacoco配置:
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>${jacoco.version}</version>
    <configuration>
        <destFile>${project.build.directory}/jacoco.exec</destFile>
        <append>true</append>
    </configuration>
    <executions>
        <execution>
            <id>jacoco-initialize</id>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>jacoco-site</id>
            <phase>verify</phase>
            <goals>
                <goal>report-aggregate</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.reporting.outputDirectory}/jacoco-aggregate</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
  • 子模块的Jacoco配置:
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>${jacoco.version}</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>jacoco-report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

6. 移除不必要的jacoco.exec复制配置

maven-resources-plugin复制jacoco.exec到输出目录的操作完全多余,Jacoco会自动生成到指定路径,移除该执行配置:

<!-- 移除以下execution节点 -->
<execution>
    <id>copy-resource</id>
    <phase>process-resources</phase>
    <goals>
        <goal>copy-resources</goal>
    </goals>
    <configuration>
        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>jacoco.exec</include>
                </includes>
            </resource>
        </resources>
    </configuration>
</execution>

7. 规范执行命令顺序

确保扫描Sonar前完成测试与报告生成,执行以下命令:

mvn clean verify jacoco:report-aggregate sonar:sonar

内容的提问来源于stack exchange,提问作者Priya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:39:46