]> source.dussan.org Git - javassist.git/commitdiff
JASSIST-271 Allow running on Java 11 by falling back to ClassLoader.defineClass for... 198/head
authorChristian Beikov <christian.beikov@gmail.com>
Sun, 29 Apr 2018 14:20:56 +0000 (16:20 +0200)
committerChristian Beikov <christian.beikov@gmail.com>
Sun, 29 Apr 2018 14:20:56 +0000 (16:20 +0200)
src/main/javassist/bytecode/ClassFile.java
src/main/javassist/util/proxy/DefineClassHelper.java

index 880c18b8e60eccb43b41b65b126d2b73d9a9b33a..5e7475a61c5cd13f2f03c2338616fd47c80f9573 100644 (file)
@@ -20,6 +20,7 @@ import java.io.DataInputStream;
 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;
@@ -123,6 +124,18 @@ public final class ClassFile {
      */
     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).
@@ -136,6 +149,10 @@ public final class ClassFile {
      * 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;
 
@@ -152,6 +169,10 @@ public final class ClassFile {
             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;
index 3ed261e5199c324533d34541661a7ddd623512c2..4d6c9f9d1598f2b5d39befb847548a454a199241 100644 (file)
@@ -21,6 +21,7 @@ import java.lang.invoke.MethodHandles;
 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;
@@ -73,8 +74,12 @@ public class DefineClassHelper
                     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);
@@ -171,11 +176,15 @@ public class DefineClassHelper
                 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.