The implementation method to be invoked for this lambda is a static bridge
method
taking this hidden class's instance as the parameter, i.e. a descriptor
referencing
a hidden class, which will fail to resolve.
0: #104 REF_invokeStatic
java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#111 ()V
#112 REF_invokeStatic
HiddenClassWithIndy.lambda$test$0:(LHiddenClassWithIndy;)V
#111 ()V
Now that a hidden class is a nestmate, should/can this bridge method be
an instance method if this class is defined as a hidden class?
Mandy
On 11/29/20 7:34 AM, Remi Forax wrote:
Hi Mandy, hi all,
it seems that when defineAnonymousClass rewrites the currentClass, it doesn't
work if there is an invokedynamic in the classfile, so defineHiddenClass fails
with a VerifyError when the hidden class is verified.
Here is an example showing the issue
---
import java.io.IOException;
import java.lang.invoke.MethodHandles;
public class HiddenClassWithIndy {
public void test() {
var a = new HiddenClassWithIndy();
Runnable r = () -> System.out.println(a);
}
public static void main(String[] args) throws IOException,
IllegalAccessException {
byte[] bytecode;
try(var input =
HiddenClassWithIndy.class.getClassLoader().getResourceAsStream(HiddenClassWithIndy.class.getName().replace('.',
'/') + ".class")) {
if (input == null) {
throw new AssertionError();
}
bytecode = input.readAllBytes();
}
var hiddenLookup = MethodHandles.lookup().defineHiddenClass(bytecode,
true);
}
}
---
The error message:
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400.test()V @9:
invokedynamic
Reason:
Type 'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400' (current
frame, stack[0]) is not assignable to 'fr/umlv/transmogrif/HiddenClassWithIndy'
Current Frame:
bci: @9
flags: { }
locals: { 'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400',
'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400' }
stack: { 'fr/umlv/transmogrif/HiddenClassWithIndy+0x0000000801002400' }
Bytecode:
0000000: bb00 0759 b700 094c 2bba 000a 0000 4db1
0000010:
at java.base/java.lang.ClassLoader.defineClass0(Native Method)
at java.base/java.lang.System$2.defineClass(System.java:2193)
at
java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClass(MethodHandles.java:2235)
at
java.base/java.lang.invoke.MethodHandles$Lookup$ClassDefiner.defineClassAsLookup(MethodHandles.java:2216)
at
java.base/java.lang.invoke.MethodHandles$Lookup.defineHiddenClass(MethodHandles.java:1952)
at
fr.umlv.transmogrif.HiddenClassWithIndy.main(HiddenClassWithIndy.java:20)
regards,
Rémi