Plugin fails on OpenJDK 11.0.8 when using includeNoLocationClasses = true
BenTilbrook opened this issue ยท 18 comments
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_HOME
to$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 (gradle/gradle#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
jacocoVersion
to 0.8.7 - set
testCoverageEnabled
to 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.
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.
@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.*"]
}