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

使用Jacoco+Gradle生成覆盖率报告报错:无法添加同名不同类

问题:Jacoco生成集成测试覆盖率报告时出现同名类冲突错误

尝试用Jacoco插件和Gradle生成集成测试覆盖率报告时,抛出以下错误:

java.lang.IllegalStateException: Can't add different class with same name: com/example/application/Application
    at org.jacoco.core.analysis.CoverageBuilder.visitCoverage(CoverageBuilder.java:106)
    at org.jacoco.core.analysis.Analyzer$1.visitEnd(Analyzer.java:99)
    at org.objectweb.asm.ClassVisitor.visitEnd(ClassVisitor.java:377)
    at org.jacoco.core.internal.flow.ClassProbesAdapter.visitEnd(ClassProbesAdapter.java:100)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:725)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:401)
    at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:116)
    at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:132)
Caused: java.io.IOException: Error while analyzing C:\Users\p-bri\.jenkins\jobs\ProjectAssignmentOne-ParallelBuildDeclarative\builds\5\jacoco\classes\java\main\com\example\application\Application.class.
    at org.jacoco.core.analysis.Analyzer.analyzerError(Analyzer.java:162)
    at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:134)
    at org.jacoco.core.analysis.Analyzer.analyzeClass(Analyzer.java:157)
    at org.jacoco.core.analysis.Analyzer.analyzeAll(Analyzer.java:193)
    at org.jacoco.core.analysis.Analyzer.analyzeAll(Analyzer.java:226)
    at hudson.plugins.jacoco.ExecutionFileLoader.analyzeStructure(ExecutionFileLoader.java:127)
Caused: java.io.IOException: While reading class directory: C:\Users\p-bri\.jenkins\jobs\ProjectAssignmentOne-ParallelBuildDeclarative\builds\5\jacoco\classes
    at hudson.plugins.jacoco.ExecutionFileLoader.analyzeStructure(ExecutionFileLoader.java:130)
    at hudson.plugins.jacoco.ExecutionFileLoader.loadBundleCoverage(ExecutionFileLoader.java:138)
    at hudson.plugins.jacoco.JacocoReportDir.parse(JacocoReportDir.java:110)
    at hudson.plugins.jacoco.JacocoBuildAction.loadRatios(JacocoBuildAction.java:331)
    at hudson.plugins.jacoco.JacocoBuildAction.load(JacocoBuildAction.java:321)
    at hudson.plugins.jacoco.JacocoPublisher.perform(JacocoPublisher.java:675)
    at jenkins.tasks.SimpleBuildStep.perform(SimpleBuildStep.java:123)
    at org.jenkinsci.plugins.workflow.steps.CoreStep$Execution.run(CoreStep.java:100)
    at org.jenkinsci.plugins.workflow.steps.CoreStep$Execution.run(CoreStep.java:70)
    at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

Jenkins声明式流水线中生成报告的阶段配置:

stage('Integration Test Coverage report') {
  steps {
    dir('') {
     jacoco exclusionPattern: '**/*Test*.class,**/groovy/**', classPattern: '**/classes', sourcePattern: '**/src/main/java', execPattern: '**/integrationTest.exec'
    }
  }
}

Jenkins日志中的匹配信息:

[JaCoCo plugin] Number of found exec files for pattern **/integrationTest.exec: 1
[JaCoCo plugin] Saving matched execfiles:  C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\build\jacoco\integrationTest.exec
[JaCoCo plugin] Saving matched class directories for class-pattern: **/classes: 
[JaCoCo plugin]  - C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\artifacts\parallel_build\reports\tests\integrationTest\classes 0 files
[JaCoCo plugin]  - C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\artifacts\sequential_build\reports\tests\integrationTest\classes 0 files
[JaCoCo plugin]  - C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\build\classes 24 files
[JaCoCo plugin]  - C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\build\reports\tests\integrationTest\classes 0 files
[JaCoCo plugin]  - C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\node_modules\semver\classes 0 files
[JaCoCo plugin]  - C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\war\WEB-INF\classes 22 files
[JaCoCo plugin] Saving matched source directories for source-pattern: **/src/main/java: 
[JaCoCo plugin] Source Inclusions: **/*.java,**/*.groovy,**/*.kt,**/*.kts
[JaCoCo plugin] Source Exclusions: 
[JaCoCo plugin] - C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\src\main\java 17 files
[JaCoCo plugin] Loading inclusions files..
[JaCoCo plugin] inclusions: []
[JaCoCo plugin] exclusions: [**/*Test*.class, **/groovy/**]

根据Jacoco FAQ,该错误源于存在同名但不同的类,但日志未明确指出具体冲突位置,请问如何定位并解决?


定位与解决方法

一、定位冲突类

  • 从报错信息明确冲突类为com/example/application/Application,结合Jenkins日志,Jacoco扫描了两个含有效类文件的目录:build/classes和war/WEB-INF/classes。直接在这两个目录下查找该类文件:
    1. 进入C:\Users\p-bri\.jenkins\workspace\ProjectAssignmentOne-ParallelBuildDeclarative\build\classes,搜索com/example/application/Application.class
    2. 进入war/WEB-INF/classes目录,同样搜索该类文件
  • 对比两个文件差异:使用javap -v命令查看字节码详情,比如分别执行javap -v build/classes/com/example/application/Application.class和javap -v war/WEB-INF/classes/com/example/application/Application.class,通过版本、方法表、常量池等信息确认是否为重复编译或打包导致的重复类。

二、解决方法

1. 精确配置Jacoco的classPattern

当前classPattern: '**/classes'会扫描所有含classes的目录,包括war包解压后的重复类目录。将其修改为指向Gradle编译生成的主类目录,避免重复扫描:

jacoco exclusionPattern: '**/*Test*.class,**/groovy/**', 
        classPattern: 'build/classes/java/main', 
        sourcePattern: 'src/main/java', 
        execPattern: 'build/jacoco/integrationTest.exec'

2. 清理冗余classes目录

检查项目构建流程,确认war/WEB-INF/classes是否为多余生成目录。如果是打包时自动复制的产物,可在生成Jacoco报告前手动清理该目录,或在Gradle构建脚本中调整打包逻辑,避免重复生成。

3. 排除war目录下的classes

若必须保留war目录,可在exclusionPattern中添加war下的classes路径,排除重复扫描:

jacoco exclusionPattern: '**/*Test*.class,**/groovy/**,**/war/WEB-INF/classes/**', 
        classPattern: '**/classes', 
        sourcePattern: '**/src/main/java', 
        execPattern: '**/integrationTest.exec'

内容的提问来源于stack exchange,提问作者Fábio Pires

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:01:16