jacoco code coverage report generator showing error : “Classes in bundle 'Code Coverage Report' do no match with execution data”

前端 未结 2 1901
鱼传尺愫
鱼传尺愫 2020-12-03 05:24

I am generating jacoco report by using jacoco:report tag. I am getting errors like :

[jacoco:report] Classes in bundle \'Code Coverage Report\' do no match          


        
相关标签:
2条回答
  • 2020-12-03 05:24

    You are getting the error related to classID. This is a concept described in detail at JaCoCo docs-site. http://www.eclemma.org/jacoco/trunk/doc/classids.html. This is a key step for supporting multiple versions of class (an appserver for example) in same JVM.

    Copying part some part of it here for visibility.

    What are class ids and how are they created?

    Class ids are 64-bit integer values, for example 0x638e104737889183 in hex notation. Their calculation is considered an implementation detail of JaCoCo. Currently ids are created with a CRC64 checksum of the raw class file.

    What can cause different class ids?

    Class ids are identical for the exact same class file only (byte-by-byte). There is a couple of reasons why you might get different class files. First compiling Java source files will result in different class files if you use a different tool chain:

    • Different compiler vendor (e.g. Eclipse vs. Oracle JDK)

    • Different compiler versions

    • Different compiler settings (e.g. debug vs. non-debug)

    Also post-processing class files (obfuscation, AspectJ, etc.) will typically change the class files. JaCoCo will work well if you simply use the same class files for runtime as well as for analysis. So the tool chain to create these class files does not matter.

    Even if the class files on the file system are the same there is possible that classes seen by the JaCoCo runtime agent are different anyways. This typically happens when another Java agent is configured before the JaCoCo agent or special class loaders pre-process the class files. Typical candidates are:

    • Mocking frameworks
    • Application servers
    • Persistence frameworks

    The same page covers possible solutions.

    What workarounds exist to deal with runtime-modified classes?

    If classes get modified at runtime in your setup there are some workarounds to make JaCoCo work anyways:

    • If you use another Java agent make sure the JaCoCo agent is specified at first in the command line. This way the JaCoCo agent should see the original class files.
    • Specify the classdumpdir option of the JaCoCo agent and use the dumped classes at report generation. Note that only loaded classes will be dumped, i.e. classes not executed at all will not show-up in your report as not covered.
    • Use offline instrumentation before you run your tests. This way classes get instrumented by JaCoCo before any runtime modification can take place. Note that in this case the report has to be generated with the original classes, not with instrumented ones.

    Edited on 22-02-2017

    How to use Offline Instrumentation: Use below task provided by Daniel Atallah.

    //Additional SourceSets can be added to the jacocoOfflineSourceSets as needed by 
    project.ext.jacocoOfflineSourceSets = [ 'main' ]
    task doJacocoOfflineInstrumentation(dependsOn: [ classes, project.configurations.jacocoAnt ]) {
        inputs.files classes.outputs.files
        File outputDir = new File(project.buildDir, 'instrumentedClasses')
        outputs.dir outputDir
        doFirst {
            project.delete(outputDir)
            ant.taskdef(
                resource: 'org/jacoco/ant/antlib.xml',
                classpath: project.configurations.jacocoAnt.asPath,
                uri: 'jacoco'
            )
            def instrumented = false
            jacocoOfflineSourceSets.each { sourceSetName ->
                if (file(sourceSets[sourceSetName].output.classesDir).exists()) {
                    def instrumentedClassedDir = "${outputDir}/${sourceSetName}"
                    ant.'jacoco:instrument'(destdir: instrumentedClassedDir) {
                        fileset(dir: sourceSets[sourceSetName].output.classesDir, includes: '**/*.class')
                    }
                    //Replace the classes dir in the test classpath with the instrumented one
                    sourceSets.test.runtimeClasspath -= files(sourceSets[sourceSetName].output.classesDir)
                    sourceSets.test.runtimeClasspath += files(instrumentedClassedDir)
                    instrumented = true
                }
            }
            if (instrumented) {
                //Disable class verification based on https://github.com/jayway/powermock/issues/375
                test.jvmArgs += '-noverify'
            }
        }
    }
    test.dependsOn doJacocoOfflineInstrumentation
    

    Now generate report using "gradlew test jacocoTestReport" command.

    0 讨论(0)
  • 2020-12-03 05:40

    JaCoCo needs the exact same class files for report generation that used at execution time. Due to different compilers and/or other tools modifying the classes, the classes might be different.

    0 讨论(0)
提交回复
热议问题