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