public static void main(String[] args) throws Throwable { MethodHandles.Lookup lookup = MethodHandles.lookup(); // mt is (char,char)String MethodType mt = MethodType.methodType(void.class, Object.class); MethodHandle mh = lookup.findVirtual(MethodHandleTest.class, "print", mt); mh = mh.bindTo(new MethodHandleTest()); mh.invoke("Hello World"); /* * Consumer cs = new PartTest_test_FuncIfImpl_0(mh); * * ArrayList list = new ArrayList(); list.add("Hello1"); list.add("Hello2"); * * list.stream().forEach(cs); */ }
private Object handleDefault(Object proxy, Method method, Object[] args) throws Throwable { // support default messages in interfaces if (method.isDefault()) { final Class<?> declaringClass = method.getDeclaringClass(); final MethodHandles.Lookup lookup = MethodHandles.publicLookup().in(declaringClass); // ensure allowed mode will not check visibility final Field f = MethodHandles.Lookup.class.getDeclaredField("allowedModes"); final int modifiers = f.getModifiers(); if (Modifier.isFinal(modifiers)) { // should be done a single time final Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(f, modifiers & ~Modifier.FINAL); f.setAccessible(true); f.set(lookup, MethodHandles.Lookup.PRIVATE); } return lookup.unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); } return null; }
@BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeShort.class, "final_v", short.class); vhField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeShort.class, "v", short.class); vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodTypeShort.class, "static_final_v", short.class); vhStaticField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodTypeShort.class, "static_v", short.class); vhArray = MethodHandles.arrayElementVarHandle(short[].class); }
@Override public void setupVarHandleSources() { // Combinations of VarHandle byte[] or ByteBuffer vhss = new ArrayList<>(); for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) { ByteOrder bo = endianess == MemoryMode.BIG_ENDIAN ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; VarHandleSource aeh = new VarHandleSource( MethodHandles.byteArrayViewVarHandle(int[].class, bo), endianess, MemoryMode.READ_WRITE); vhss.add(aeh); VarHandleSource bbh = new VarHandleSource( MethodHandles.byteBufferViewVarHandle(int[].class, bo), endianess, MemoryMode.READ_WRITE); vhss.add(bbh); } }
/** * Creates the {@link MethodHandle} for the megamorphic call site * using {@link ClassValue} and {@link MethodHandles#exactInvoker(MethodType)}: */ private MethodHandle createMegamorphicHandle() { final MethodType type = type(); final ClassValue<MethodHandle> megamorphicCache = new ClassValue<MethodHandle>() { @Override protected MethodHandle computeValue(Class<?> receiverType) { // it's too stupid that we cannot throw checked exceptions... (use rethrow puzzler): try { return lookup(flavor, name, receiverType).asType(type); } catch (Throwable t) { Def.rethrow(t); throw new AssertionError(); } } }; return MethodHandles.foldArguments(MethodHandles.exactInvoker(type), MEGAMORPHIC_LOOKUP.bindTo(megamorphicCache)); }
public void testTwoTypes() throws Throwable { CallSite site = DefBootstrap.bootstrap(MethodHandles.publicLookup(), "toString", MethodType.methodType(String.class, Object.class), 0, DefBootstrap.METHOD_CALL, ""); MethodHandle handle = site.dynamicInvoker(); assertDepthEquals(site, 0); assertEquals("5", (String)handle.invokeExact((Object)5)); assertDepthEquals(site, 1); assertEquals("1.5", (String)handle.invokeExact((Object)1.5f)); assertDepthEquals(site, 2); // both these should be cached assertEquals("6", (String)handle.invokeExact((Object)6)); assertDepthEquals(site, 2); assertEquals("2.5", (String)handle.invokeExact((Object)2.5f)); assertDepthEquals(site, 2); }
@BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessFloat.class, "final_v", float.class); vhField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessFloat.class, "v", float.class); vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodHandleAccessFloat.class, "static_final_v", float.class); vhStaticField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodHandleAccessFloat.class, "static_v", float.class); vhArray = MethodHandles.arrayElementVarHandle(float[].class); }
private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) { final HandleAndAssumptions handleAndAssumptions = inv.getValidOptimisticInvocation(new Supplier<MethodHandle>() { @Override public MethodHandle get() { return inv.getInvokerOrConstructor(constructor); } }); final MethodHandle handle = handleAndAssumptions.handle; final SwitchPoint assumptions = handleAndAssumptions.assumptions; final MethodHandle target; if(assumptions == null) { target = handle; } else { final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor); target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink)); } cs.setTarget(target.asType(cs.type())); }
void testFilterArguments(int nargs, int pos) throws Throwable { countTest(); MethodHandle target = varargsList(nargs); MethodHandle filter = varargsList(1); filter = filter.asType(filter.type().generic()); Object[] argsToPass = randomArgs(nargs, Object.class); if (verbosity >= 3) System.out.println("filter "+target+" at "+pos+" with "+filter); MethodHandle target2 = MethodHandles.filterArguments(target, pos, filter); // Simulate expected effect of filter on arglist: Object[] filteredArgs = argsToPass.clone(); filteredArgs[pos] = filter.invokeExact(filteredArgs[pos]); List<Object> expected = Arrays.asList(filteredArgs); Object result = target2.invokeWithArguments(argsToPass); if (verbosity >= 3) System.out.println("result: "+result); if (!expected.equals(result)) System.out.println("*** fail at n/p = "+nargs+"/"+pos+": "+Arrays.asList(argsToPass)+" => "+result+" != "+expected); assertEquals(expected, result); }
public void testTargetClassInOpenModule() throws Throwable { // m1/p1.Type Class<?> clazz = Class.forName("p1.Type"); assertEquals(clazz.getModule().getName(), "m1"); // ensure that this module reads m1 Module thisModule = getClass().getModule(); Module m1 = clazz.getModule(); thisModule.addReads(clazz.getModule()); assertTrue(m1.isOpen("p1", thisModule)); Lookup lookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()); assertTrue(lookup.lookupClass() == clazz); assertTrue(lookup.hasPrivateAccess()); // get obj field MethodHandle mh = lookup.findStaticGetter(clazz, "obj", Object.class); Object obj = mh.invokeExact(); }
@BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeChar.class, "final_v", char.class); vhField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodTypeChar.class, "v", char.class); vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodTypeChar.class, "static_final_v", char.class); vhStaticField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodTypeChar.class, "static_v", char.class); vhArray = MethodHandles.arrayElementVarHandle(char[].class); }
/** * Teleport from publicLookup to public type in unnamed module * * [A0] has PUBLIC access */ public void testPublicLookupToUnnamedModule() throws Exception { Lookup lookup = MethodHandles.publicLookup().in(unnamedClass); assertTrue(lookup.lookupModes() == PUBLIC); // A0 // m1 findConstructor(lookup, p1_Type1, void.class); findConstructorExpectingIAE(lookup, p2_Type2, void.class); // m2 findConstructor(lookup, q1_Type1, void.class); findConstructorExpectingIAE(lookup, q2_Type2, void.class); // java.base findConstructor(lookup, Object.class, void.class); findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class); // unnamed findConstructor(lookup, unnamedClass, void.class); }
@BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessShort.class, "final_v", short.class); vhField = MethodHandles.lookup().findVarHandle( VarHandleTestMethodHandleAccessShort.class, "v", short.class); vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodHandleAccessShort.class, "static_final_v", short.class); vhStaticField = MethodHandles.lookup().findStaticVarHandle( VarHandleTestMethodHandleAccessShort.class, "static_v", short.class); vhArray = MethodHandles.arrayElementVarHandle(short[].class); }
void testThrowException(Class<?> returnType, Throwable thrown) throws Throwable { countTest(); Class<? extends Throwable> exType = thrown.getClass(); MethodHandle target = MethodHandles.throwException(returnType, exType); //System.out.println("throwing with "+target+" : "+thrown); MethodType expectedType = MethodType.methodType(returnType, exType); assertEquals(expectedType, target.type()); target = target.asType(target.type().generic()); Throwable caught = null; try { Object res = target.invokeExact((Object) thrown); fail("got "+res+" instead of throwing "+thrown); } catch (Throwable ex) { if (ex != thrown) { if (ex instanceof Error) throw (Error)ex; if (ex instanceof RuntimeException) throw (RuntimeException)ex; } caught = ex; } assertSame(thrown, caught); }
private MethodHandle getTestMH(Class clazz, String methodName, Object param, boolean isNegativeTest) throws Exception { MethodType mType = (param != null) ? MethodType.genericMethodType(1) : MethodType.methodType(String.class); MethodHandles.Lookup lookup = MethodHandles.lookup(); if (!isNegativeTest) { return methodName.equals("staticMethod") ? lookup.findStatic(clazz, methodName, mType) : lookup.findVirtual(clazz, methodName, mType); } else { return methodName.equals("staticMethod") ? lookup.findVirtual(clazz, methodName, mType) : lookup.findStatic(clazz, methodName, mType); } }
@Test public void testReturnFromArg() throws Throwable { MethodHandles.Lookup l = MethodHandles.lookup(); MethodHandle consumeIdentity = dropArguments( identity(String.class), 1, int.class, int.class); MethodHandle consumeVoid = l.findStatic( PermuteArgsReturnVoidTest.class, "consumeVoid", MethodType.methodType(void.class, String.class, int.class, int.class)); MethodHandle f = MethodHandles.foldArguments(consumeIdentity, consumeVoid); MethodHandle p = MethodHandles.permuteArguments(f, MethodType.methodType(String.class, String.class, int.class, int.class), 0, 2, 1); String s = (String) p.invoke("IN", 0, 0); Assert.assertEquals(s.getClass(), String.class); Assert.assertEquals(s, "IN"); }
public static void main(String[] args) throws ParseException { Options options = new Options() .addOption("region", true, "the region containing the kinesis stream") .addOption("bucket", true, "the bucket containing the raw event data") .addOption("prefix", true, "the prefix of the objects containing the raw event data") .addOption("stream", true, "the name of the kinesis stream the events are sent to") .addOption("speedup", true, "the speedup factor for replaying events into the kinesis stream") .addOption("aggregate", "turn on aggregation of multiple events into a kinesis record") .addOption("seek", true, "start replaying events at given timestamp") .addOption("statisticsFrequency", true, "print statistics every statisticFrequency ms") .addOption("help", "print this help message"); CommandLine line = new DefaultParser().parse(options, args); if (line.hasOption("help")) { new HelpFormatter().printHelp(MethodHandles.lookup().lookupClass().getName(), options); } else { StreamPopulator populator = new StreamPopulator( line.getOptionValue("region", "eu-west-1"), line.getOptionValue("bucket", "aws-bigdata-blog"), line.getOptionValue("prefix", "artifacts/flink-refarch/data/"), line.getOptionValue("stream", "taxi-trip-events"), line.hasOption("aggregate"), Float.valueOf(line.getOptionValue("speedup", "6480")), Long.valueOf(line.getOptionValue("statisticsFrequency", "60000")) ); if (line.hasOption("seek")) { populator.seek(new DateTime(line.getOptionValue("seek"))); } populator.populate(); } }
/** * Generate test with an invokedynamic, a static bootstrap method without extra args and no arg * to the target method. */ private void generateMethodTest1(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test1", "()V", null, null); MethodType mt = MethodType.methodType( CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmLookupStatic", mt.toMethodDescriptorString(), false); mv.visitInvokeDynamicInsn("targetMethodTest1", "()V", bootstrap); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that * chain. * @param relinkAndInvoke the ultimate fallback for the chain passed from the dynamic linker. * @return a method handle for prune-and-invoke */ private MethodHandle makePruneAndInvokeMethod(final MethodHandle relinkAndInvoke, final MethodHandle prune) { // Bind prune to (this, relink) final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relinkAndInvoke); // Make it ignore all incoming arguments final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList()); // Invoke prune, then invoke the call site target with original arguments return MethodHandles.foldArguments(MethodHandles.exactInvoker(type()), ignoreArgsPrune); }
@Test public static void testCountedLoopStateInitializedToNull() throws Throwable { MethodHandle loop = MethodHandles.countedLoop(MethodHandles.constant(int.class, 5), MethodHandles.empty(methodType(String.class)), Counted.MH_stateBody); assertEquals(Counted.MT_bodyDeterminesState, loop.type()); assertEquals("sssssnull01234", loop.invoke()); }
@DataProvider static Object[][] omitTrailingArguments() { MethodHandle c = TryFinally.MH_voidCleanup; return new Object[][]{ {c}, {MethodHandles.dropArguments(c, 1, int.class)}, {MethodHandles.dropArguments(c, 1, int.class, long.class)}, {MethodHandles.dropArguments(c, 1, int.class, long.class, Object.class, int.class)}, {MethodHandles.dropArguments(c, 1, int.class, long.class, Object.class, int.class, long.class)} }; }
private static MethodHandle dropReceiver(final MethodHandle mh, final Class<?> receiverClass) { MethodHandle newHandle = MethodHandles.dropArguments(mh, 0, receiverClass); // NOTE: this is a workaround for the fact that dropArguments doesn't preserve vararg collector state. if(mh.isVarargsCollector() && !newHandle.isVarargsCollector()) { final MethodType type = mh.type(); newHandle = newHandle.asVarargsCollector(type.parameterType(type.parameterCount() - 1)); } return newHandle; }
@Test(dataProvider = "countedLoopBodyParameters") public static void testCountedLoopBodyParameters(MethodType countType, MethodType initType, MethodType bodyType) throws Throwable { MethodHandle loop = MethodHandles.countedLoop( MethodHandles.empty(countType), initType == null ? null : MethodHandles.empty(initType), MethodHandles.empty(bodyType)); // The rule: If body takes the minimum number of parameters, then take what countType offers. // The initType has to just roll with whatever the other two agree on. int innerParams = (bodyType.returnType() == void.class ? 1 : 2); MethodType expectType = bodyType.dropParameterTypes(0, innerParams); if (expectType.parameterCount() == 0) expectType = expectType.insertParameterTypes(0, countType.parameterList()); assertEquals(expectType, loop.type()); }
/** * A bootstrap method for invokedynamic * @param lookup a lookup object * @param methodName methodName * @param type method type * @return CallSite for method */ public static CallSite bootstrapMethod(MethodHandles.Lookup lookup, String methodName, MethodType type) throws IllegalAccessException, NoSuchMethodException { MethodType mtype = MethodType.methodType(boolean.class, new Class<?>[]{int.class, long.class, float.class, double.class, String.class}); return new ConstantCallSite(lookup.findVirtual(lookup.lookupClass(), methodName, mtype)); }
public static CallSite bsmCreateCallSite( MethodHandles.Lookup caller, String name, MethodType type, MethodHandle mh) throws Throwable { // Using mh to create the call site fails when run on Art. See b/36957105 for details. final MethodHandle targetMH = MethodHandles.lookup().findSpecial(Super.class, "targetMethodTest5", MethodType.methodType(void.class), InvokeCustom.class); return new ConstantCallSite(targetMH); }
static MethodHandle tweak(MethodHandle mh, int argPos, Class<?> type) { MethodType mt = mh.type(); if (argPos == -1) mt = mt.changeReturnType(type); else mt = mt.changeParameterType(argPos, type); return MethodHandles.explicitCastArguments(mh, mt); }
public static CallSite bsmCreateCallCallingtargetMethodTest8( MethodHandles.Lookup caller, String name, MethodType type, MethodHandle mh) throws Throwable { // Using mh to create the call site fails when run on Art. See b/36957105 for details. final MethodHandle targetMH = MethodHandles.lookup().findVirtual( J.class, "targetMethodTest8", MethodType.methodType(void.class)); return new ConstantCallSite(targetMH); }
public static StackInspector handle(How how) throws Exception { Lookup lookup = MethodHandles.lookup(); MethodHandle mh = lookup.findStatic(Caller.class, "create", MethodType.methodType(StackInspector.class, How.class)); try { return (StackInspector) mh.invoke(how); } catch (Error | Exception x) { throw x; } catch(Throwable t) { throw new AssertionError(t); } }
@Override protected GuardedInvocation findGetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) { final Object self = request.getReceiver(); final Class<?> returnType = desc.getMethodType().returnType(); if (returnType == Object.class && JSType.isString(self)) { try { return new GuardedInvocation(MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType()), NashornGuards.getStringGuard()); } catch (final LookupException e) { //empty. Shouldn't happen. Fall back to super } } return super.findGetIndexMethod(desc, request); }
public void testInvokePolymorphic() { MethodType mt = MethodType.methodType(String.class, Integer.class, int.class, String.class); MethodHandles.Lookup lk = MethodHandles.lookup(); try { MethodHandle mh = lk.findVirtual(getClass(), "buildString", mt); System.out.println(mh.invoke(this, null, 1, "string")); } catch (Throwable t) { t.printStackTrace(); } }
@Test public static void testLoopFacWithVoidState() throws Throwable { // like testLoopFac, but with additional void state that outputs a dot MethodHandle[] counterClause = new MethodHandle[]{Fac.MH_zero, Fac.MH_inc}; MethodHandle[] accumulatorClause = new MethodHandle[]{Fac.MH_one, Fac.MH_mult, Fac.MH_pred, Fac.MH_fin}; MethodHandle[] dotClause = new MethodHandle[]{null, Fac.MH_dot}; MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause, dotClause); assertEquals(Fac.MT_fac, loop.type()); assertEquals(120, loop.invoke(5)); }
/** * Generic method which converts a method signature without arguments to a Supplier instance * Uses MethodHandles instead of Reflection API * * @param obj * @param methodName * @param type * @param <T> * @return * @throws NoSuchMethodException * @throws SecurityException * @throws IllegalAccessException */ public static <T> Supplier<T> createGenericReflectionSupplierNoArgs(Object obj, String methodName, Class<? extends Object> type) throws NoSuchMethodException, SecurityException, IllegalAccessException { MethodHandle methodHandle = MethodHandles.lookup().findVirtual(obj.getClass(), methodName, MethodType.methodType(type)); MethodHandle ready = methodHandle.bindTo(obj); return () -> { T t = null; try { return (T)type.cast(ready.invoke()); } catch (Throwable throwable) { throwable.printStackTrace(); } return t; }; }
@Test(dataProvider = "accessModesProvider", expectedExceptions = UnsupportedOperationException.class) public void methodHandleInvoke(VarHandle.AccessMode accessMode) throws Throwable { VarHandle v = handle(); // Try a reflective invoke using a MethodHandle MethodHandle mh = MethodHandles.lookup().unreflect( VarHandle.class.getMethod(accessMode.methodName(), Object[].class)); // Use invoke to avoid WrongMethodTypeException for // non-signature-polymorphic return types Object o = (Object) mh.invoke(v, new Object[]{}); }
/** Looks up generic method, with a dynamic cast to the receiver's type. (compound assignment) */ public static MethodHandle dynamicCast(MethodHandle target) { // adapt dynamic receiver cast to the generic method MethodHandle cast = DYNAMIC_RECEIVER_CAST.asType(MethodType.methodType(target.type().returnType(), target.type().returnType(), target.type().parameterType(0))); // drop the RHS parameter cast = MethodHandles.dropArguments(cast, 2, target.type().parameterType(1)); // combine: f(x,y) -> g(f(x,y), x, y); return MethodHandles.foldArguments(cast, target); }
/** Looks up generic method, with a dynamic cast to the specified type. (explicit assignment) */ public static MethodHandle dynamicCast(MethodHandle target, Class<?> desired) { // adapt dynamic cast to the generic method desired = MethodType.methodType(desired).wrap().returnType(); // bind to the boxed type MethodHandle cast = DYNAMIC_CAST.bindTo(desired); return MethodHandles.filterReturnValue(target, cast); }
@BeforeClass public static void setUpClass() throws Exception { client = new JerseyClientBuilder(SERVICE.getEnvironment()) .build(MethodHandles.lookup().lookupClass().getName()) .property(CONNECT_TIMEOUT, 2000) .property(READ_TIMEOUT, 3000) .register(new LoggingFeature(getLogger(DEFAULT_LOGGER_NAME), INFO, PAYLOAD_ANY, 1024)); }
@Override public MethodHandle getter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) { try { final MethodHandle mh = explicitLookup.findGetter(clazz, name, type); return debug(mh, "getter", explicitLookup, clazz, name, type); } catch (final NoSuchFieldException | IllegalAccessException e) { throw new LookupException(e); } }
private static MethodHandle unbox(Wrapper wrap, int kind) { // kind 0 -> strongly typed with NPE // kind 1 -> strongly typed but zero for null, // kind 2 -> asType rules: accept multiple box types but only widening conversions with NPE // kind 3 -> explicitCastArguments rules: allow narrowing conversions, zero for null WrapperCache cache = UNBOX_CONVERSIONS[kind]; MethodHandle mh = cache.get(wrap); if (mh != null) { return mh; } // slow path switch (wrap) { case OBJECT: case VOID: throw new IllegalArgumentException("unbox "+wrap); } // look up the method String name = "unbox" + wrap.wrapperSimpleName(); MethodType type = unboxType(wrap, kind); try { mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type); } catch (ReflectiveOperationException ex) { mh = null; } if (mh != null) { if (kind > 0) { boolean cast = (kind != 2); mh = MethodHandles.insertArguments(mh, 1, cast); } if (kind == 1) { // casting but exact (null -> zero) mh = mh.asType(unboxType(wrap, 0)); } return cache.put(wrap, mh); } throw new IllegalArgumentException("cannot find unbox adapter for " + wrap + (kind <= 1 ? " (exact)" : kind == 3 ? " (cast)" : "")); }
public void testNoNullGuardAdd() throws Throwable { DefBootstrap.MIC site = (DefBootstrap.MIC) DefBootstrap.bootstrap(MethodHandles.publicLookup(), "add", MethodType.methodType(Object.class, int.class, Object.class), 0, DefBootstrap.BINARY_OPERATOR, 0); MethodHandle handle = site.dynamicInvoker(); expectThrows(NullPointerException.class, () -> { assertNotNull((Object)handle.invokeExact(5, (Object)null)); }); }
@Override public MethodHandle setter(final MethodHandles.Lookup explicitLookup, final Class<?> clazz, final String name, final Class<?> type) { try { final MethodHandle mh = explicitLookup.findSetter(clazz, name, type); return debug(mh, "setter", explicitLookup, clazz, name, type); } catch (final NoSuchFieldException | IllegalAccessException e) { throw new LookupException(e); } }