import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
*/
public static final int JAVA_9 = 53;
+ /**
+ * The major version number of class files
+ * for JDK 10.
+ */
+ public static final int JAVA_10 = 54;
+
+ /**
+ * The major version number of class files
+ * for JDK 11.
+ */
+ public static final int JAVA_11 = 55;
+
/**
* The major version number of class files created
* from scratch. The default value is 47 (JDK 1.3).
* if the JVM supports <code>java.util.function.Function</code>.
* It is 53 (JDK 1.9)
* if the JVM supports <code>java.lang.reflect.Module</code>.
+ * It is 54 (JDK 10)
+ * if the JVM supports <code>java.util.List.copyOf(Collection)</code>.
+ * It is 55 (JDK 11)
+ * if the JVM supports <code>java.util.Optional.isEmpty()</code>.
*/
public static final int MAJOR_VERSION;
ver = JAVA_8;
Class.forName("java.lang.Module");
ver = JAVA_9;
+ List.class.getMethod("copyOf", Collection.class);
+ ver = JAVA_10;
+ Class.forName("java.util.Optional").getMethod("isEmpty");
+ ver = JAVA_11;
}
catch (Throwable t) {}
MAJOR_VERSION = ver;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Method;
import java.security.ProtectionDomain;
+import java.util.List;
import javassist.CannotCompileException;
import javassist.bytecode.ClassFile;
throw new IllegalAccessError("Access denied for caller.");
try {
SecurityActions.TheUnsafe usf = SecurityActions.getSunMiscUnsafeAnonymously();
+ List<Method> defineClassMethod = usf.methods.get("defineClass");
+ // On Java 11+ the defineClass method does not exist anymore
+ if (null == defineClassMethod)
+ return null;
MethodHandle meth = MethodHandles.lookup()
- .unreflect(usf.methods.get("defineClass").get(0));
+ .unreflect(defineClassMethod.get(0));
return new ReferencedUnsafe(usf, meth);
} catch (Throwable e) {
throw new RuntimeException("cannot initialize", e);
ClassLoader loader, ProtectionDomain protectionDomain) throws ClassFormatError;
}
- private static final SecuredPrivileged privileged = ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9
- ? SecuredPrivileged.JAVA_9
- : ClassFile.MAJOR_VERSION >= ClassFile.JAVA_7
- ? SecuredPrivileged.JAVA_7
- : SecuredPrivileged.JAVA_OTHER;
+ // Java 11+ removed sun.misc.Unsafe.defineClass, so we fallback to invoking defineClass on
+ // ClassLoader until we have an implementation that uses MethodHandles.Lookup.defineClass
+ private static final SecuredPrivileged privileged = ClassFile.MAJOR_VERSION > ClassFile.JAVA_10
+ ? SecuredPrivileged.JAVA_OTHER
+ : ClassFile.MAJOR_VERSION >= ClassFile.JAVA_9
+ ? SecuredPrivileged.JAVA_9
+ : ClassFile.MAJOR_VERSION >= ClassFile.JAVA_7
+ ? SecuredPrivileged.JAVA_7
+ : SecuredPrivileged.JAVA_OTHER;
/**
* Loads a class file by a given class loader.