Consider the following code that is meant to generate an invokedynamic
instruction using ASM:
// BOOTSTRAP = new Handle(->
// CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType methodType, Class<?> someClass)
mv.visitInvokeDynamicInsn("foo", "(I)I", BOOTSTRAP, Type.INT_TYPE);
When decompiling the generated class using ASMifier, the relevant line becomes
mv.visitInvokeDynamicInsn("foo", "(I)I", new Handle(/* SNIP (same as BOOTSTRAP) */),
Type.getType("LI;"));
¯¯¯¯¯
As you can see, the Type.INT_TYPE
has turned into a literal reference to a reference type named I
. As this doesn't exist, the JVM complains at runtime with java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: I
.
What I wanted to do instead was pass int.class
(the Class
instance for the primitive type int
, or the value of the Integer.TYPE
constant) to my bootstrap
method as the argument for someClass
. However, it seems like ASM did not properly understand or support this.
Can this be considered an ASM bug, and is there a workaround for this?