]> source.dussan.org Git - javassist.git/commitdiff
MethodHandles for JDK7+.
authornickl- <github@jigsoft.co.za>
Fri, 27 Oct 2017 05:36:38 +0000 (07:36 +0200)
committernickl- <github@jigsoft.co.za>
Sun, 12 Nov 2017 21:49:21 +0000 (23:49 +0200)
Java 7 and 8 does support method handles so we can cater for them. When doing
repeated invokes to the same method, keeping a reference to the Method handle
is much faster than reflection. Also the API is cleaner not having to Object[]
args etc. Worth the effort...

src/main/javassist/util/proxy/DefineClassHelper.java

index ee565d8054b6360e3e8a379a8898df02ebfd2349..208a6f0c8d9ad7d30fc2cf4088b5c9f79381128d 100644 (file)
@@ -90,6 +90,33 @@ public class DefineClassHelper
                         protectionDomain);
             }
         },
+        JAVA_7 {
+            private final MethodHandle defineClass = getDefineClassMethodHandle();
+            private final MethodHandle getDefineClassMethodHandle()
+            {
+                try {
+                    return SecurityActions.getMethodHandle(ClassLoader.class,
+                        "defineClass", new Class[] {
+                            String.class, byte[].class, int.class, int.class,
+                            ProtectionDomain.class
+                        });
+                } catch (NoSuchMethodException e) {
+                    throw new RuntimeException("cannot initialize", e);
+                }
+            }
+
+            @Override
+            protected Class<?> defineClass(String name, byte[] b, int off, int len,
+                    ClassLoader loader, ProtectionDomain protectionDomain) throws ClassFormatError
+            {
+                try {
+                    return (Class<?>) defineClass.invokeWithArguments(
+                            loader, name, b, off, len, protectionDomain);
+                } catch (Throwable e) {
+                    if (e instanceof RuntimeException) throw (RuntimeException) e;
+                    if (e instanceof ClassFormatError) throw (ClassFormatError) e;
+                    throw new ClassFormatError(e.getMessage());
+                }
             }
         },
         JAVA_OTHER {
@@ -125,16 +152,18 @@ public class DefineClassHelper
                     SecurityActions.setAccessible(defineClass, false);
                 }
             }
+
         };
 
         public abstract Class<?> defineClass(String name, byte[] b, int off, int len,
                 ClassLoader loader, ProtectionDomain protectionDomain) throws ClassFormatError;
-
-
     }
-    private static final SecuredPrivileged privileged = ClassFile.MAJOR_VERSION < ClassFile.JAVA_9
-            ? SecuredPrivileged.JAVA_OTHER
-            : SecuredPrivileged.JAVA_9;
+
+    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;
 
     /**
      * Loads a class file by a given class loader.