Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.ExceptionInInitializerError with Java-16 | j.l.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module

I have cglib as a transitive dependency in a Maven project. Despite adding what I believe to be the correct --add-opens I can't get the library to work with Java 16.

How do I get cglib to work with Java 16? I raised this issue on the github page.

Minimal reproducible example:

Main.java

import net.sf.cglib.proxy.Enhancer;

public class Main {
    public static void main(String[] args) {
        new Enhancer();
    }
}

With Java 15:

javac -cp cglib-3.3.0.jar Main.java

java --add-opens java.base/java.lang=ALL-UNNAMED -cp cglib-3.3.0.jar:asm-7.1.jar:. Main

Picked up _JAVA_OPTIONS: -Duser.language=en -Duser.country=GB
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by net.sf.cglib.core.ReflectUtils$1 (file:/Users/rbain/Desktop/cglib-3.3.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of net.sf.cglib.core.ReflectUtils$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

With Java 16:

javac -cp cglib-3.3.0.jar Main.java

java --add-opens java.base/java.lang=ALL-UNNAMED -cp cglib-3.3.0.jar:asm-7.1.jar:. Main

Exception in thread "main" java.lang.ExceptionInInitializerError
    at Main.main(Main.java:5)
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @11739fa6
    at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)
    at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
    at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:96)
    at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:94)
    at net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
    at net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
    at net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
    at net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:174)
    at net.sf.cglib.core.KeyFactory.create(KeyFactory.java:153)
    at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
    ... 1 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @11739fa6
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
    at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
    at net.sf.cglib.core.ReflectUtils$1.run(ReflectUtils.java:61)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:554)
    at net.sf.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:52)
    at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
    at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:332)
    ... 13 more
like image 771
Robert Bain Avatar asked Apr 06 '21 18:04

Robert Bain


People also ask

What is exceptionininitializererror in Java?

- GeeksforGeeks How to Resolve Java.lang.ExceptionInInitializerError In Java? An unexpected, unwanted event that disturbed the normal flow of a program is called an Exception. 1. Checked Exception

Why am I getting a JavaFX error when adding a module?

You are getting this error because your runtime PATH to javafx is probably incorrect or missing. where $FX-PATH should be set or replaced with mentioned JavaFX path. If you need to add more modules, you can specify them in --add-modules parameter.

How do you handle exceptions in Java?

Another way of handling the exception is the use of “throws” keyword. The method definition should be modified as shown in the following example. Here, method intParsingMethod () throws the exception object that is thrown by Integer.parseInt (“25k”) to its calling method, which is main () in this case.

Why do I get Ava NoClassDefFoundError JavaFX?

But still I get ava.lang.NoClassDefFoundError: javafx/application/Application which indicates that the jre cannot find the FX classes. Show activity on this post. You are getting this error because your runtime PATH to javafx is probably incorrect or missing. where $FX-PATH should be set or replaced with mentioned JavaFX path.


1 Answers

Since JDK 16, the default for the --illegal-access option is deny, so “deep reflection” to JDK classes fails.

You can override the behavior by specifying --illegal-access=permit, but you have to be aware of JEP 403: Strongly Encapsulate JDK Internals which is about closing that possibility in a future version, so this option is only a temporary solution.

The permanent solution is to update cglib to a compatible version if/once it exists. The attempt to access ClassLoader.defineClass suggests that the library wants to add classes to a particular context, which can be done via MethodHandles.lookup().defineClass instead (since Java 9). So the code only has to switch to the new way of adding classes.

like image 96
Holger Avatar answered Sep 19 '22 05:09

Holger