Jacoco fails on Gradle 7.0.2 and Kotlin 1.5.10

Viewed 5493

Today I updated gradle and kotlin dependencies in android studio.

The new versions are these:

kotlin_version = "1.5.10"
...
jacoco {
    toolVersion = "0.8.6"
}
...
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip

The test coverage report task fails with the following error:

2021-05-27T16:57:49.150+0200 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter] Executing actions for task ':consumerkit:testDebugUnitTestCoverage'.
2021-05-27T16:57:49.304+0200 [DEBUG] [org.codehaus.groovy.vmplugin.VMPluginFactory] Trying to create VM plugin `org.codehaus.groovy.vmplugin.v9.Java9` by checking `java.lang.Module`, but failed:
java.lang.ClassNotFoundException: java.lang.Module
        at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at org.codehaus.groovy.vmplugin.VMPluginFactory.lambda$createPlugin$0(VMPluginFactory.java:61)
        at java.security.AccessController.doPrivileged(Native Method)
4 Answers

I already had the

jacoco {
    toolVersion = "0.8.7"
}

configured but it was not working anyway, what fixed the problem was to follow this comment here

  1. In your module build.gradle switch back to:
android {
    //....
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

don't worry, it won't break anything if you were not using Java 11 language features yet, AGP 7 is still compatible with JDK 8 as target.

  1. Then you need to force AGP to use the 0.8.7 version and not the default 0.8.3 one. In your allprojects block in the root build.gradle file, add this:
allprojects {
  //... other things

  // workaround to fix an auto-import of a lower Jacoco version
  resolutionStrategy {
    eachDependency { details ->
      if ('org.jacoco' == details.requested.group) {
        details.useVersion "0.8.7"
      }
    }
  }
}

and now it should work using:

AGP 7.0.X
Kotlin 1.5.X
JDK 11 (embedded with AS)

Simply doing

jacoco {
    toolVersion = "0.8.7"
}

was not enough for me. I also had to override the version that Android was using so that the androidJacocoAnt dependency also uses 0.8.7. (./gradlew app:dependencies) Simply add this to your gradle too

android.jacoco.version = "0.8.7"

It's quite old thread, but these solutions did not solve my problems completely in Android project (actually written in Java - not in Kotlin), so I will add my solutions here. Maybe someone will find it helpful.

Except of updating jacoco toolVersion to 0.8.7, I also had to update execution data in my jacoco config as follows:

project.afterEvaluate {
  tasks.create(name: "${unitTestTask}Coverage", type: JacocoReport, 
  dependsOn: [
    "$unitTestTask",
    ":sdk:testDebugUnitTest",
    ":sdk:connectedCheck"
  ]) {

   /* all jacoco custom configuration goes here... */

    executionData(fileTree(dir: "$buildDir", includes: [
      "jacoco/testDebugUnitTest.exec",        
      "outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
      "outputs/code_coverage/debugAndroidTest/connected/*coverage.ec"
    ]))
  }
}

in this configuration I had to add the following line:

"outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec"

which wasn't there before because file with generated report used by sonar was generated in the new location. Report is generated with gradle task testDebugUnitTestCoverage. After all of that, I'm able to generate test coverage report including connected/instrumentation Android tests and regular unit tests in java via sonar.

Related