I am building a method "by hand" in ByteBuddy. The method I'm building has one parameter of type ProductType
. Let's say it looks like this:
public ProductType frob(ProductType product) {
// stuff that I'm implementing and asking about goes here
}
Inside that method I am building the equivalent of:
product.foo(); // more on this below; foo() has a void return type, which may be important
return product; // FixedValue.argument(0)
This works fine when I build an Implementation
like this:
MethodCall.invoke(fooMethodDescription) // invoke foo()...
.onArgument(0) // ...on product...
.andThen(FixedValue.argument(0)); // ...and then return product
(I hope I've typed that right.)
If, however, I build an Implementation
like this:
InvokeDynamic.bootstrap(...) // look up foo()'s MethodHandle via my bootstrap method...
.invoke("foo", TypeDescription.VOID) // ...invoke the method handle with a return type of void...
.withArgument(0) // ..."on" the first and only argument (product) and "with" no other arguments...
.andThen(FixedValue.argument(0)); // ...and then return product
…with, of course, the proper InvokeDynamic
recipe, the resulting class cannot be verified because of an Operand stack underflow
error (Attempt to pop empty stack
).
I have a similar InvokeDynamic
recipe used many places elsewhere so I know that my problem is not with the InvokeDynamic
usage. Rather, it seems to be with the composing? maybe? Is it possible that MethodCall
and InvokeDynamic
behave differently, even though both are Implementation
s? Maybe InvokeDynamic
doesn't push something on the operand stack (maybe just in the case of void
returns?) whereas MethodCall
does? Is there something I'm missing in the andThen()
usage?
Using ByteBuddy 1.11.2.
As you pointed out correctly, this is a bug in Byte Buddy that is now fixed. Thanks for that. It will be released with version 1.11.3.