Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8172817

LambdaMetafactory should use the referenced class of static implMethods

    Details

    • Type: Bug
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: 9
    • Fix Version/s: tbd
    • Component/s: core-libs
    • Labels:
      None

      Description

      When the 'implMethod' passed to LambdaMetafactory is a static method, the call to 'revealDirect' on the MethodHandle can result in an unexpected access error if the declaring class of the MethodHandle is inaccessible while the original referenced class is accessible: see JDK-8172815.

      Once that bug is fixed, the bytecode generated by InnerClassLambdaMetafactory will use the inaccessible declaring class in its generated bytecode, potentially leading to internal resolution errors or other surprises. The appropriate class to use in the bytecode is the original *referenced* class. Unfortunately, per JDK-8068253, this is not made available by the MethodHandle API.

      Once *that* bug is fixed, LambdaMetafactory should be updated to use the referenced class, not the declaring class.

      A test case, which ought to run without error:

      ---

      package p1;
      class A {
          public static void staticMethod() {}
          public void instanceMethod() {}
      }

      ---

      package p1;
      public class B extends A {}

      ---

      package p2;
      public class C extends p1.B {}

      ---


      import java.lang.invoke.*;

      public class Test {

          public static void main(String... args) throws Throwable {
              MethodType toVoid = MethodType.methodType(void.class);
              MethodHandles.Lookup lookup = MethodHandles.lookup();
              MethodHandle mh = lookup.findStatic(p2.C.class, "staticMethod", toVoid);
              
              System.out.println("Begin linkage...");
              CallSite cs = LambdaMetafactory.metafactory(lookup, "run", MethodType.methodType(Runnable.class), toVoid, mh, toVoid);
              System.out.println("Begin capture...");
              Runnable r = (Runnable) cs.getTarget().invokeExact();
              System.out.println("Begin invocation...");
              r.run();
              System.out.println("Done");
          }

      }

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                mchung Mandy Chung
                Reporter:
                dlsmith Dan Smith
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated: