Skip to main content

Command Palette

Search for a command to run...

Javassist and JDK 16

Updated
•1 min read•View as Markdown

As you may know, in JDK 16 illegal access become denied, so instead of warning you'll get an error like this:

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 @270421f5
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)

Of course, you can simply revert the previous behavior with the VM argument: --illegal-access=permit, but this option will be removed in JDK 17.

The solution could be found in javassits issue: you must not use CtClass#toClass() or toClass(classloader) anymore, instead use toClass(neighborClass).

BUT this method will only work for java >= 9, so if you need to support java 8, you'll have to use both methods:

// some class from classpath (neighbor) to inherit classloader and domain permissions from
Class<?> baseClass = ...;
boolean isJava8 = System.getProperty("java.version").startsWith("1.8");

CtClass generated = ...;
Class<?> result = isJava8 
         // java 8 only
         ? generated.toClass(baseClass.getClassLoader(), baseClass.getProtectionDomain())
         // java 9 and above
         : generated.toClass(baseClass);

The minimal required javassist is 3.24.

More from this blog

Vyacheslav Rusakov's Blog

20 posts