Jacoco Gradle脱机检测问题

时间:2019-06-19 15:42:01

标签: java gradle code-coverage jacoco gradle-plugin

我正在使用离线工具进行Gradle Multi项目中的代码覆盖,但出现以下错误:

Caused by: java.lang.IllegalStateException: <Class Name>  is already instrumented.

build.gradle如下:

allprojects {

    apply plugin: 'java'
    apply plugin: 'jacoco'
}

 configurations {
        jacocoAnt
    }

jacoco {
    toolVersion = "0.8.0+"
}

subprojects {
    dependencies {
        testCompile 'junit:junit:4.11'
    }

    jacocoTestReport {
        println 'first here in jacocoTestReport'
        additionalSourceDirs = files(sourceSets.main.allSource.srcDirs)
        sourceDirectories = files(sourceSets.main.allSource.srcDirs)
        classDirectories =  files(sourceSets.main.output)
        println 'in jacocoTestReport    :    ' + sourceSets.main.output
        //println 'in jacocoTestReport    :    ' + "instrumentedClasses/main"
        //classDirectories =  files("instrumentedClasses")
        reports {
            html.enabled = true
            xml.enabled = true
            csv.enabled = false
        }
    }
}

task jacocoRootReport(type: org.gradle.testing.jacoco.tasks.JacocoReport) {
    dependsOn {
         [subprojects.test]
    }
    classDirectories = files()
    println 'second here in jacocoRootReport'
    additionalSourceDirs = files(subprojects.sourceSets.main.allSource.srcDirs)
    sourceDirectories = files(subprojects.sourceSets.main.allSource.srcDirs)
    //classDirectories =  files(subprojects.sourceSets.main.output)
        subprojects.each { lSubProject ->
                File outputDir = new File(lSubProject.buildDir, 'instrumentedClasses')
                if (outputDir.exists()) {
                        classDirectories += files(outputDir)
                        println 'output dir found for ' + outputDir
                }
        }
    executionData = files(subprojects.jacocoTestReport.executionData)
    reports {
        html.enabled = true
        xml.enabled = true
        csv.enabled = false
    }
    onlyIf = {
        true
    }
    doFirst {
        executionData = files(executionData.findAll {
            it.exists()
        })
    }
}

project.ext.jacocoOfflineSourceSets = [ 'main' ]
task instrument(dependsOn: [classes, project.configurations.jacocoAnt]) {
        subprojects.each { lSubProject ->
                inputs.files classes.outputs.files
                File outputDir = new File(lSubProject.buildDir, 'instrumentedClasses')
                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(lSubProject.sourceSets[sourceSetName].output.classesDir).exists()) {
                    def instrumentedClassedDir = "${outputDir}"
                    ant.'jacoco:instrument'(destdir: instrumentedClassedDir) {
                        fileset(dir: lSubProject.sourceSets[sourceSetName].output.classesDir)
                    }
                    //Replace the classes dir in the test classpath with the instrumented one
                    //lSubProject.sourceSets.test.runtimeClasspath -= files(lSubProject.sourceSets[sourceSetName].output.classesDir)
                    //lSubProject.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 instrument
        }

使用以下命令执行build.gradle:

./gradlew jacocoRootReport --no-daemon --stacktrace

1 个答案:

答案 0 :(得分:0)

异常消息

<Class Name> is already instrumented.

changed in JaCoCo version 0.8.2

Cannot process instrumented class <Class Name>. Please supply original non-instrumented classes.

强调一个事实,即需要非工具化的原始类,而您的jacocoRootReport任务使用的是instrumentedClasses目录,其中包含已检测的类。