Skip to content

Plugin fails on OpenJDK 11.0.8 when using includeNoLocationClasses = true #193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
BenTilbrook opened this issue Apr 22, 2021 · 18 comments

Comments

@BenTilbrook
Copy link

BenTilbrook commented Apr 22, 2021

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

TestJacoco.zip

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)
@charlesng
Copy link

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.

@jiechic
Copy link

jiechic commented May 8, 2021

the same problem

@prolland
Copy link

adding this to my script did the trick :

afterEvaluate {
    tasks.withType(Test) {
        jacoco.excludes = ['jdk.internal.*']
    }
}

@im-not-josh
Copy link

@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.

@vramasam
Copy link

vramasam commented Jul 9, 2021

Hello, After making this change, I am getting zero coverage in the report. Any inputs here please?

@prolland
Copy link

prolland commented Jul 16, 2021

@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.

@henriquenfaria
Copy link
Contributor

@vramasam @prolland Setting testCoverageEnabled to false did the trick for me as well.
No idea what's going on here :)

@vramasam
Copy link

vramasam commented Jul 19, 2021

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
Copy link

vramasam commented Jul 20, 2021

Hello @prolland Any thoughts that would help me here?

@prolland
Copy link

@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'
        }

@vramasam
Copy link

@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.

@mrgoltstein
Copy link

@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.

@vramasam
Copy link

vramasam commented Aug 3, 2021

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.

@mrgoltstein
Copy link

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.

@vramasam
Copy link

@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.

@0neel
Copy link

0neel commented Dec 23, 2021

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.*']
    }
  }
}

@vramasam
Copy link

@mrgoltstein The above solution worked finally with latest gradle version. Thank you

@grndvl1
Copy link

grndvl1 commented Jul 18, 2022

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.*"]
  }

hurricup added a commit to Camelcade/Perl5-IDEA that referenced this issue Nov 10, 2022
- For some reason subproject classes considered as noLocationClasses
- Excluding internals required to avoid exception, see vanniktech/gradle-android-junit-jacoco-plugin#193 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants