public void testRunnableProxy0() throws Throwable { if (CAN_SKIP_WORKING) return; startTest("testRunnableProxy"); MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandle run = lookup.findStatic(lookup.lookupClass(), "runForRunnable", MethodType.methodType(void.class)); Runnable r = MethodHandleProxies.asInterfaceInstance(Runnable.class, run); testRunnableProxy(r); assertCalled("runForRunnable"); }
/** * MethodHandleProxies will add qualified export of sun.invoke from java.base * to a dynamic module */ @Test public static void testRunnableMethodHandle() throws Exception { MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(void.class); MethodHandle mh = lookup.findStatic(ProxyForMethodHandle.class, "runForRunnable", mt); Runnable proxy = MethodHandleProxies.asInterfaceInstance(Runnable.class, mh); proxy.run(); Class<?> proxyClass = proxy.getClass(); Module target = proxyClass.getModule(); assertDynamicModule(target, proxyClass.getClassLoader(), proxyClass); }
/** * MethodHandleProxies will add qualified export of sun.invoke from java.base * to a dynamic module */ @Test static void testRunnableMethodHandle() throws Exception { MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodType mt = MethodType.methodType(void.class); MethodHandle mh = lookup.findStatic(ProxyForMethodHandle.class, "runForRunnable", mt); Runnable proxy = MethodHandleProxies.asInterfaceInstance(Runnable.class, mh); proxy.run(); Class<?> proxyClass = proxy.getClass(); Module target = proxyClass.getModule(); assertDynamicModule(target, proxyClass.getClassLoader(), proxyClass); }
public void testProxy() throws NoSuchMethodException, IllegalAccessException { MethodHandle m = MethodHandles.lookup().findStatic(MHProxiesTest.class, "m", MethodType.methodType(Byte.class, int.class)); Sam s = MethodHandleProxies.asInterfaceInstance(Sam.class, m); assertEquals(66d, s.m(66)); }
private static Object proxy(Class<?> interfaze, MethodHandle target) { return MethodHandleProxies.asInterfaceInstance(interfaze, target); }
public <I> I forInterface (final Class<I> iface) { if (iface == null) { throw new IllegalArgumentException ("iface cannot be null"); } if (!iface.isInterface ()) { throw new IllegalArgumentException (String.format ("%s must be an interface", iface.toString ())); } final Method[] methods = iface.getMethods (); if (methods.length != 1) { throw new IllegalArgumentException (String.format ("%s must have exactly one method", iface.toString ())); } final Method method = methods[0]; final ExecutableExpression<C, ?> lastExpression = plan.getExecutionSteps().get (plan.getExecutionSteps ().size () - 1).executor.expression; // Return types must match: if (!lastExpression.getResultType ().equals (method.getReturnType ())) { throw new IllegalArgumentException (String.format ( "Method %s has unexpected return type %s, while expecting %s", method.toString (), lastExpression.getResultType ().toString (), method.getReturnType ().toString () )); } // Interface must have proper input types: final Class<?>[] parameterTypes = method.getParameterTypes (); if (parameterTypes.length != inputClasses.size () + 1) { throw new IllegalArgumentException (String.format ( "Method %s has an invalid number of arguments %d, expected %d", method.toString (), parameterTypes.length, inputClasses.size () + 1 )); } if (!parameterTypes[0].isAssignableFrom (contextClass)) { throw new IllegalArgumentException (String.format ( "First parameter of %s must is of unexpected type %s, expecting (a subclass of) %s", method.toString (), parameterTypes[0].toString (), contextClass.toString () )); } final Class<?> actualContextClass = parameterTypes[0]; for (int i = 0; i < inputClasses.size (); ++ i) { if (!parameterTypes[i + 1].isAssignableFrom (inputClasses.get (i))) { throw new IllegalArgumentException (String.format ( "Parameter %d of %s must be assignable from %s", i + 1, method.toString (), inputClasses.get (i).toString () )); } } // Bind the execute handle to the final MethodHandle executeThisHandle = executeHandle.bindTo (this); // Convert to a specific type: final Class<?> returnType = lastExpression.getResultType (); final Class<?>[] castParameterTypes = new Class<?>[inputClasses.size () + 1]; castParameterTypes[0] = actualContextClass; for (int i = 0; i < inputClasses.size (); ++ i) { castParameterTypes[i + 1] = inputClasses.get (i); } final MethodHandle castExecuteHandle = executeThisHandle .asVarargsCollector (Object[].class) .asType (MethodType.methodType (returnType, castParameterTypes)); // Create an interface wrapper for the resulting method handle: return MethodHandleProxies.asInterfaceInstance (iface, castExecuteHandle); }
/** * Turns a function reference into an instance of a single-method interface. * * @param interfaceClass the target single-method interface class. * @param target the implementation function reference. * @return an instance of {@code interfaceClass}. * @see java.lang.invoke.MethodHandleProxies#asInterfaceInstance(Class, java.lang.invoke.MethodHandle) */ public static Object asInterfaceInstance(Object interfaceClass, Object target) { require(interfaceClass instanceof Class, "interfaceClass must be a Class"); require(target instanceof FunctionReference, "target must be a FunctionReference"); return MethodHandleProxies.asInterfaceInstance((Class<?>) interfaceClass, ((FunctionReference) target).handle()); }