From 7d5eb53d1241ca8bdd4624a9f5a61834bf4dc053 Mon Sep 17 00:00:00 2001 From: nickl- Date: Fri, 27 Oct 2017 07:36:38 +0200 Subject: [PATCH] MethodHandles for JDK7+. 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... --- .../util/proxy/DefineClassHelper.java | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/javassist/util/proxy/DefineClassHelper.java b/src/main/javassist/util/proxy/DefineClassHelper.java index ee565d80..208a6f0c 100644 --- a/src/main/javassist/util/proxy/DefineClassHelper.java +++ b/src/main/javassist/util/proxy/DefineClassHelper.java @@ -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. -- 2.39.5