]> source.dussan.org Git - javassist.git/commitdiff
Add getMethodHandle to SecurityActions.
authornickl- <github@jigsoft.co.za>
Fri, 27 Oct 2017 04:43:49 +0000 (06:43 +0200)
committernickl- <github@jigsoft.co.za>
Sun, 12 Nov 2017 21:49:21 +0000 (23:49 +0200)
The main advantage is that we can do the privileged setAccessible during creation and
then freely invoke via the authorized method handle.

As per the javadocs:
Access checks are applied in the factory methods of Lookup, when a method handle is created.
his is a key difference from the Core Reflection API, since java.lang.reflect.Method.invoke
performs access checking against every caller, on every call.

The performance boost is just a bonus.

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

index ed1ec9814a134c90ad7f228f2d7cb82463645bd9..272ccfec4b8bd38e5d4dd7d4bbd5e945e341decc 100755 (executable)
@@ -15,6 +15,8 @@
  */
 package javassist.util.proxy;
 
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
@@ -51,8 +53,32 @@ class SecurityActions {
         }
     }
 
-    static Method getDeclaredMethod(final Class clazz, final String name,
-            final Class[] types) throws NoSuchMethodException {
+    static MethodHandle getMethodHandle(final Class<?> clazz, final
+                String name, final Class<?>[] params) throws NoSuchMethodException
+    {
+        try {
+            return AccessController.doPrivileged(
+                new PrivilegedExceptionAction<MethodHandle>() {
+                    public MethodHandle run() throws IllegalAccessException,
+                            NoSuchMethodException, SecurityException {
+                        Method rmet = clazz.getDeclaredMethod(name, params);
+                        rmet.setAccessible(true);
+                        MethodHandle meth = MethodHandles.lookup().unreflect(rmet);
+                        rmet.setAccessible(false);
+                        return meth;
+                    }
+                });
+        }
+        catch (PrivilegedActionException e) {
+            if (e.getCause() instanceof NoSuchMethodException)
+                throw (NoSuchMethodException) e.getCause();
+            throw new RuntimeException(e.getCause());
+        }
+    }
+
+    static Method getDeclaredMethod(final Class<?> clazz, final String name,
+            final Class<?>[] types) throws NoSuchMethodException
+    {
         if (System.getSecurityManager() == null)
             return clazz.getDeclaredMethod(name, types);
         else {