Lookup.defineAnonymousClass() vs indy
Remi Forax
forax at univ-mlv.fr
Sun Nov 29 15:34:14 UTC 2020
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
More information about the core-libs-dev
mailing list