Javassist and JDK 16

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.