gradle-android-junit-jacoco-plugin
gradle-android-junit-jacoco-plugin copied to clipboard
Plugin fails on OpenJDK 11.0.8 when using includeNoLocationClasses = true
The plugin fails with the below error when running jacocoTestReport, if using OpenJDK 11.0.8 (as included in Android Studio 4.2 RC1), and when includeNoLocationClasses = true (which seemingly is required many common setups in order for coverage to be reported correctly.
Steps
- Use OpenJDK 11.0.8 by setting
JAVA_HOMEto$ANDROID_STUDIO_PATH/Contents/jre/jdk/Contents/Home(may vary depending on OS) - Extract sample project and CD into it
- Run
./gradlew jacocoTestReportRelease
Expected
Build succeeds
Actual
Build fails
Error
> Task :app:testReleaseUnitTest FAILED
java.lang.NoClassDefFoundError: jdk/internal/reflect/GeneratedSerializationConstructorAccessor1
at jdk.internal.reflect.GeneratedSerializationConstructorAccessor1.newInstance(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.io.ObjectStreamClass.newInstance(ObjectStreamClass.java:1092)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2150)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1668)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:482)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:440)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.deserializeWorker(SystemApplicationClassLoaderWorker.java:153)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:121)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: java.lang.ClassNotFoundException: jdk.internal.reflect.GeneratedSerializationConstructorAccessor1
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 12 more
Sample project
Environment
AGP 4.1.2
Plugin version 0.16.0
OpenJDK 11.0.8
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
OpenJDK 64-Bit Server VM (build 11.0.8+10-b944.6916264, mixed mode)
I face the same issue in circle ci when compile with JDK11, i found that the root cause is this one (https://github.com/gradle/gradle/issues/5184), i tried the solution (jacoco.excludes = ['jdk.internal.*']) it doesn't work, seem like this plugin doesn't expose this field for us to set it externally.
the same problem
adding this to my script did the trick :
afterEvaluate {
tasks.withType(Test) {
jacoco.excludes = ['jdk.internal.*']
}
}
@prolland Thanks so much for this! I was stuck on this for a while. I had the jacoco.excludes but i wasnt using that inside the afterEvaluate - that is the key! If I understood groovy better I would open a PR to fix this.
Hello, After making this change, I am getting zero coverage in the report. Any inputs here please?
@vramasam I do have the same problem, but I believe it is due to the upgrade to android gradle plugin 4.2.0 and not jdk11 (both come with the same studio upgrade if I remember well). I had posted a comment here for that and I see there is another comment with a potential workaround. I tried and I now have code coverage again :
- set
jacocoVersionto 0.8.7 - set
testCoverageEnabledto false Don't ask me why ... Maybe some sort of conflict since I think the android gradle plugin has some sort of code coverage support for instrumented tests.
@vramasam @prolland Setting testCoverageEnabled to false did the trick for me as well.
No idea what's going on here :)
Hello all, Actually I am not using testCoverageEnabled in my project. It's not required for our project. We are using ./gradlew jacocoTestReportDebug to generate the report.
Here I have not upgraded the Android plugin and I have just upgraded the Java version.
Below are the steps I tired: Step 1: Till now used Java8 , upgrade this to Java11. Step 2: Because of above upgrade got this error (Caused by: java.lang.ClassNotFoundException: jdk.internal.reflect.GeneratedSerializationConstructorAccessor1) Step 3: So used this below code snippet: tasks.withType(Test) { includeNoLocationClasses = true jacoco.excludes = ['jdk.internal.*'] }
After that I am getting coverage report is zero.
Hello @prolland Any thoughts that would help me here?
@vramasam No sorry nothing more. Check that you have the testCoverageEnabled set to false in your android config :
buildTypes {
debug {
testCoverageEnabled false
minifyEnabled false
}
release {
signingConfig signingConfigs.release
testCoverageEnabled false
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
@prolland Okay Thank you.
But I am not sure above setting hold good for the AGP 7.0.0. Again it started zero coverage with AGP 7.0.0.
@prolland Okay Thank you.
But I am not sure above setting hold good for the AGP 7.0.0. Again it started zero coverage with AGP 7.0.0.
I have a possible workaround for you: in my experience switching the Gradle JDK to Adopt OpenJ9 resolves this issue. In Android Studio: open settings > Build, Execution, Deployment > Build Tools > Gradle, change the Gradle JDK to adopt-openj9-11. Might require a reboot.
Hello @mrgoltstein Thank you for the inputs. But as part of Android Gradle Plugin 7.0.0 , its mandatory to upgrade and use Java 11 for building the Android projects. so we cant downgraded the Java version.
Also, If anyone have a workaround or proper fix with Java 11 and with AGP 7.0.0, please provide the inputs.
Hello @mrgoltstein Thank you for the inputs. But as part of Android Gradle Plugin 7.0.0 , its mandatory to upgrade and use Java 11 for building the Android projects. so we cant downgraded the Java version.
Also, If anyone have a workaround or proper fix with Java 11 and with AGP 7.0.0, please provide the inputs.
Hi @vramasam I think the name of the SDK might be throwing you off here - adopt-openj9-11 is Java 11. OpenJ9 is the name of the SDK implementation, not an indication of which Java version it is.
@mrgoltstein Okay Thank you for the explanation. I have tried with OpenJ9 with Android Gradle plugin 7.0.1 but I have no luck, still its shows zero percentage coverage.
For me, resolving the jdk classes issue required some additional changes in the above snippet.
I had to access jacoco.excludes inside of the closure using explicitly specified it..
Otherwise the issue was still present.
I also wrapped it with subprojects block.
So the whole config looks like (I put it into root project's build.gradle):
junitJacoco {
includeNoLocationClasses = true
}
subprojects {
afterEvaluate {
tasks.withType(Test) {
// fixes https://github.com/vanniktech/gradle-android-junit-jacoco-plugin/issues/193
it.jacoco.excludes = ['jdk.internal.*']
}
}
}
@mrgoltstein The above solution worked finally with latest gradle version. Thank you
I can't do the same for kotlin DSL jacoco seems to be defined but excludes is not a reference. exclude is in red
tasks.withType<Test>() {
jacoco.exclude = ["jdk.internal.*"]
}