Junit5: Illegal Reflective Access on JDK 9+

Created on 14 Sep 2017  路  10Comments  路  Source: junit-team/junit5

Overview

The following components are not yet working without illegal reflective access operations.

Gradle 4.5.1 with Groovy groovy-all-2.4.12.jar

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.codehaus.groovy.vmplugin.v7.Java7$1 (file:/~/.gradle/wrapper/dists/gradle-4.5.1-bin/a5vbgfvpwtoqz8v2cdivxz28k/gradle-4.5.1/lib/groovy-all-2.4.12.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int)
WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.vmplugin.v7.Java7$1

Deliverables

  • [x] Update Gradle (providing Groovy) to version w/o illegal reflective access opertions.
  • [x] Updated AssertJ to version 3.9.1 via #1301
Java 9+10+11... build

Most helpful comment

In the case of AssertJ then it looks like it has a re-packaged cglib that is hacking into ClassLoader.defineClass. They need to be steered towards using java.lang.invoke.MethodHandles.Lookup.defineClass instead.

All 10 comments

In the case of AssertJ then it looks like it has a re-packaged cglib that is hacking into ClassLoader.defineClass. They need to be steered towards using java.lang.invoke.MethodHandles.Lookup.defineClass instead.

@AlanBateman -- using JDK-10 "out-of-the-box" we now face issues with Mockito. See log https://travis-ci.org/junit-team/junit5/builds/296747184 -- which contains a lot of:

  JUnit Jupiter:TestFactoryTestDescriptorTests:streamsFromTestFactoriesShouldBeClosed()
    MethodSource [className = 'org.junit.jupiter.engine.descriptor.TestFactoryTestDescriptorTests', methodName = 'streamsFromTestFactoriesShouldBeClosed', methodParameterTypes = '']
    => org.mockito.exceptions.base.MockitoException: 

Mockito cannot mock this class: interface org.junit.jupiter.api.extension.ExtensionContext.

Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.

Java               : 10
JVM vendor name    : Oracle Corporation
JVM vendor version : 10-ea+29
JVM name           : Java HotSpot(TM) 64-Bit Server VM
JVM version        : 10-ea+29
JVM info           : mixed mode
OS name            : Linux
OS version         : 4.11.6-041106-generic

Underlying exception : java.lang.UnsupportedOperationException: Cannot define class using reflection

The root cause is that ByteBuddy does not support Java 10, yet:

Caused by: java.lang.UnsupportedOperationException: Cannot define class using reflection
    at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Unavailable.defineClass(ClassInjector.java:821)
    at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:185)
    at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.load(ClassLoadingStrategy.java:187)
    at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:79)
    at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:4456)
    at org.mockito.internal.creation.bytebuddy.SubclassBytecodeGenerator.mockClass(SubclassBytecodeGenerator.java:115)
...
Caused by: java.lang.IllegalArgumentException: Unknown Java version: 10
    at net.bytebuddy.ClassFileVersion.ofJavaVersion(ClassFileVersion.java:135)
    at net.bytebuddy.ClassFileVersion$VersionLocator$ForJava9CapableVm.locate(ClassFileVersion.java:357)
    at net.bytebuddy.ClassFileVersion.ofThisVm(ClassFileVersion.java:147)
...

Upgrading to Mockito 2.11.7 (using ByteBuddy 1.7.9) fixes the issue.

:+1:

Updated overview and deliverables.

Only Groovy 3 has to be shipped with Gradle, methinks. :)

Still relevant, same issue, using Groovy 2.5.7 bundled with Gradle 5.5.1 (running on JDK 12):

> Task :junit-jupiter-engine:test
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.codehaus.groovy.vmplugin.v7.Java7$1 (file:/home/vsts_azpcontainer/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.7/99907efe4b69f800c42584386f5d668e4d952bd5/groovy-2.5.7.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int)
WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.vmplugin.v7.Java7$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

We're not using the Groovy version bundled in Gradle anymore. I just tried upgrading our testImplementation dependency to to 3.0.0-beta2 and the warning is gone. Since this affects only our tests, I don't think we'll have to wait for the final release. WDYT?

_"What are you waiting for, Christmas?!"_

Meaning, yes, let's do it.

Cheers!

Was this page helpful?
0 / 5 - 0 ratings