JDK-8016281 : The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2013-06-10
  • Updated: 2017-05-17
  • Resolved: 2013-07-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8 b99Fixed
Related Reports
Blocks :  
Duplicate :  
Description
This is a needed fix in the interface between the compiler (javac) and the metafactory (in java.lang.invoke).  So changes to both sides are needed.  The interface is the bootstrap parameters of an invokedynamic call.  The name should be encoded as a String and the type as a MethodType.

Currently a MethodHandle is used to pass the SAM method type and name.  Using MethodHandle is conceptually wrong since, due to separate compilation, the class information may be incorrect at run-time.  In these cases, a failure (which should not occur) will happen at run-time.  For example:

I.java:

    interface I {
    }

    interface J extends I {
       int m(int x);
    }


C.java:

    class C {
       public static void main(String... args) {
         J jj = x -> x * x;
         System.out.println(jj.m(9));
       }
    }

After C.java is compiled, I.java is re-compiled as:

    interface I {
       int m(int x);
    }

    interface J extends I {
    }

When run:

    Exception in thread "main" java.lang.IncompatibleClassChangeError
             at
    java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:384)
             at C.main(C.java)
    Caused by: java.lang.IllegalAccessException: no such method:
    J.m(int)int/invokeInterface
             at
    java.lang.invoke.MemberName.makeAccessException(MemberName.java:759)
             at
    java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:880)
             at
    java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1037)
             at
    java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1341)
             at
    java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:382)
             ... 1 more
    Caused by: java.lang.AbstractMethodError: J.m(I)I
             at java.lang.invoke.MethodHandleNatives.resolve(Native Method)
             at
    java.lang.invoke.MemberName$Factory.resolve(MemberName.java:852)
             at
    java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:877)
             ... 4 more

Comments
See JDK-8019635 for additional discussion copied from an email thread.
11-07-2013