aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornickl- <github@jigsoft.co.za>2017-10-27 06:43:49 +0200
committernickl- <github@jigsoft.co.za>2017-11-12 23:49:21 +0200
commit31b7faa0bc15d62d5c390096a02cebed344a620d (patch)
treef6663cd67abc47984facd379f6fc52b60c508449
parent12cdc2182b3bb33481ba1a954dfffbc9b1c3690f (diff)
downloadjavassist-31b7faa0bc15d62d5c390096a02cebed344a620d.tar.gz
javassist-31b7faa0bc15d62d5c390096a02cebed344a620d.zip
Add getMethodHandle to SecurityActions.
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.
-rwxr-xr-xsrc/main/javassist/util/proxy/SecurityActions.java30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/main/javassist/util/proxy/SecurityActions.java b/src/main/javassist/util/proxy/SecurityActions.java
index ed1ec981..272ccfec 100755
--- a/src/main/javassist/util/proxy/SecurityActions.java
+++ b/src/main/javassist/util/proxy/SecurityActions.java
@@ -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 {