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