@Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, @Nullable Object... args) throws Throwable { // Because the service interface might not be public, we need to use a MethodHandle lookup // that ignores the visibility of the declaringClass. Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class); constructor.setAccessible(true); return constructor.newInstance(declaringClass, -1 /* trusted */) .unreflectSpecial(method, declaringClass) .bindTo(object) .invokeWithArguments(args); }
@Override MethodHandle lookup(Method method) throws ReflectiveOperationException { Constructor<Lookup> constructor = this.constructor.orElseThrow(() -> new IllegalStateException( "Could not obtain MethodHandles.lookup constructor")); return constructor.newInstance(method.getDeclaringClass()).unreflectSpecial(method, method.getDeclaringClass()); }
private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class .getDeclaredConstructor(Class.class, int.class); if (!constructor.isAccessible()) { constructor.setAccessible(true); } final Class<?> declaringClass = method.getDeclaringClass(); return constructor .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC) .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); }
static Object getFallback(Method fallbackMethod, ExecutionContextWithInvocationContext ctx) throws IllegalAccessException, InstantiationException, IllegalArgumentException, InvocationTargetException, Throwable { // This should work in Java 8 Class<?> declaringClazz = fallbackMethod.getDeclaringClass(); Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class); constructor.setAccessible(true); return constructor.newInstance(declaringClazz).in(declaringClazz).unreflectSpecial(fallbackMethod, declaringClazz).bindTo(ctx.getTarget()) .invokeWithArguments(ctx.getParameters()); }
@Override MethodHandle lookup(Method method) throws ReflectiveOperationException { Constructor<Lookup> constructor = this.constructor.orElseThrow(() -> new IllegalStateException( "Could not obtain MethodHandles.lookup constructor")); return constructor.newInstance(method.getDeclaringClass()).unreflectSpecial(method, method.getDeclaringClass()); }
public DefaultMethodHandler(Method defaultMethod) { try { Class<?> declaringClass = defaultMethod.getDeclaringClass(); Field field = Lookup.class.getDeclaredField("IMPL_LOOKUP"); field.setAccessible(true); Lookup lookup = (Lookup) field.get(null); this.unboundHandle = lookup.unreflectSpecial(defaultMethod, declaringClass); } catch (NoSuchFieldException | IllegalAccessException ex) { throw new IllegalStateException(ex); } }
@Override public Object invoke(final Object proxy, final MethodInfo methodInfo, final Configuration config) throws Throwable { final Class<?> declaringClass = methodInfo.getMethod().getDeclaringClass(); final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class .getDeclaredConstructor(Class.class, int.class); constructor.setAccessible(true); return constructor.newInstance(declaringClass, MethodHandles.Lookup.PRIVATE) .unreflectSpecial(methodInfo.getMethod(), declaringClass) .bindTo(proxy) .invokeWithArguments(methodInfo.getArgs()); } }
public DefaultMethodHandler(Method defaultMethod) { try { Class<?> declaringClass = defaultMethod.getDeclaringClass(); Field field = Lookup.class.getDeclaredField("IMPL_LOOKUP"); field.setAccessible(true); Lookup lookup = (Lookup) field.get(null); this.unboundHandle = lookup.unreflectSpecial(defaultMethod, declaringClass); } catch (NoSuchFieldException | IllegalAccessException ex) { throw new IllegalStateException(ex); } }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final Class<?> declaringClass= method.getDeclaringClass(); return constructor.newInstance(declaringClass, MethodHandles.Lookup.PRIVATE).unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); } };
@Override MethodHandle lookup(Method method) throws ReflectiveOperationException { if (!isAvailable()) { throw new IllegalStateException("Could not obtain MethodHandles.lookup constructor!"); } Constructor<Lookup> constructor = this.constructor.get(); return constructor.newInstance(method.getDeclaringClass()).unreflectSpecial(method, method.getDeclaringClass()); }
private Object handleDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { MethodHandles.Lookup lookup = METHOD_LOOKUP_CTOR.newInstance( method.getDeclaringClass(), MethodHandles.Lookup.PRIVATE); return lookup.unreflectSpecial(method, method.getDeclaringClass()) .bindTo(proxy) .invokeWithArguments(args); } }
import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ReflectiveDefaultMethodCallExample { static interface Hello { default String hello() { return "Hello"; } } public static void main(String[] args) throws Throwable{ Hello target = //new Hello(){}; (Hello)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{Hello.class}, (Object proxy, Method method, Object[] arguments) -> null); Method method = Hello.class.getMethod("hello"); Object result = MethodHandles.lookup() .in(method.getDeclaringClass()) .unreflectSpecial(method,method.getDeclaringClass()) .bindTo(target) .invokeWithArguments(); System.out.println(result); //Hello } }
@UsesJava7 private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class .getDeclaredConstructor(Class.class, int.class); if (!constructor.isAccessible()) { constructor.setAccessible(true); } final Class<?> declaringClass = method.getDeclaringClass(); return constructor .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC) .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); }
private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class .getDeclaredConstructor(Class.class, int.class); if (!constructor.isAccessible()) { constructor.setAccessible(true); } final Class<?> declaringClass = method.getDeclaringClass(); return constructor .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC) .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); }
private Object handleDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { MethodHandles.Lookup lookup = METHOD_LOOKUP_CTOR.newInstance( method.getDeclaringClass(), MethodHandles.Lookup.PRIVATE); return lookup.unreflectSpecial(method, method.getDeclaringClass()) .bindTo(proxy) .invokeWithArguments(args); } }
| MethodHandles.Lookup.PROTECTED | MethodHandles.Lookup.PACKAGE) .unreflectSpecial(method, method.getDeclaringClass()) .bindTo(proxy) .invokeWithArguments();
.unreflectSpecial(method, proxyType) .bindTo(proxy) .invokeWithArguments(args);
@Override public Object getInvokeSpecialHandle(final Method method, final Object receiver) { if (LOOKUP_Constructor==null) { return super.getInvokeSpecialHandle(method, receiver); } if (!method.isAccessible()) { AccessController.doPrivileged(new PrivilegedAction() { @Override public Object run() { method.setAccessible(true); return null; } }); } Class declaringClass = method.getDeclaringClass(); try { return LOOKUP_Constructor. newInstance(declaringClass, -1). unreflectSpecial(method, declaringClass). bindTo(receiver); } catch (ReflectiveOperationException e) { throw new GroovyBugError(e); } }
@Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, @Nullable Object... args) throws Throwable { // Because the service interface might not be public, we need to use a MethodHandle lookup // that ignores the visibility of the declaringClass. Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class); constructor.setAccessible(true); return constructor.newInstance(declaringClass, -1 /* trusted */) .unreflectSpecial(method, declaringClass) .bindTo(object) .invokeWithArguments(args); }
static Object callDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { // Call the default method implementation - https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/ Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class); constructor.setAccessible(true); Class<?> declaringClass = method.getDeclaringClass(); return constructor.newInstance(declaringClass, MethodHandles.Lookup.PUBLIC | MethodHandles.Lookup.PRIVATE) .unreflectSpecial(method, declaringClass) .bindTo(proxy) .invokeWithArguments(args); } }