JDK-8044748 : JVM cannot access constructor though ::new reference although can call it directly
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-06-04
  • Updated: 2015-01-21
  • Resolved: 2014-06-24
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 JDK 9
8u40Fixed 9 b22Fixed
Related Reports
Relates :  
Relates :  
Description
Code:

$ cat Test.java
public class Test  {

    interface Constructor {
        public MyTest execute(int i);
    }

    public class MyTest {
        public MyTest(int i) { System.out.println("Constructor executed " + i); }
    }

    public Constructor getConstructor() {
        return MyTest::new;
    }

    public static void main(String argv[]) {
        new Test().call();
    }

    public void call() {
        MyTest mt = new MyTest(0);

        Constructor c1 = MyTest::new;
        c1.execute(1);

        Constructor c2 = getConstructor();
        c2.execute(2);

        Constructor c3 = new Constructor() {
            public MyTest execute(int i) {
                return new MyTest(3);
            }
        };
        c3.execute(3);

        Constructor c4 = new Constructor() {
            public MyTest execute(int i) {
                Constructor c = MyTest::new;
                return c.execute(i);
            }
        };
        c4.execute(4);
    }
}

It could be compiled sucessfully but then run fails with exception:

$ java Test
Constructor executed 0
Constructor executed 1
Constructor executed 2
Constructor executed 3
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
	at java.lang.invoke.CallSite.makeSite(CallSite.java:328)
	at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
	at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
	at Test$2.execute(Test.java:38)
	at Test.call(Test.java:42)
	at Test.main(Test.java:17)
Caused by: java.lang.invoke.LambdaConversionException: Type mismatch in captured lambda parameter 0: expecting class Test$2, found class Test
	at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:256)
	at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
	at java.lang.invoke.CallSite.makeSite(CallSite.java:289)
	... 5 more

That is, java can instantiate object with direct constructor invocation and cannot do this through constructor reference. Should be equivalent access:
JLS 15.13.1. : "treating the method reference expression as if it were a class instance creation expression".
JLS 15.13.3. : "the body of the invocation method has the effect of a class instance creation expression" and "The enclosing instance for the new object, if any, is derived from the site of the method reference expression, as specified in ��15.9.2."
JLS 15.9.2. describes the rules of determining enclosing Instances, and declares compile-time errors in other cases. No run-time errors declared.
Comments
Test(s) was added with this push --- URL: http://hg.openjdk.java.net/jdk9/dev/langtools/rev/2b6b96ed3878 User: rfield Date: 2014-06-25 18:22:47 +0000
27-06-2014

Need SQE-OK before the RT will review and consider approval. And as the comment says above - what release would this be deferred to?
18-06-2014

Robert: are you saying this will not be fixed in any 8u release?
16-06-2014

8u20-defer-request: 8037404, 8038776, 8044737, and 8044748 form a cluster of issues related to inadequate handling of constructor references to nested classes in method references. They cause crashes of the compiler and/or the running user code, and thus are high impact. They have been reported in at least five cases in fully supported code and thus this is medium likelihood. The workaround is to manually convert them to lambdas which is a low hurdle workaround. Thus ILM of HML. The fix requires rearchitecting of how method references are handled, with hundreds of lines of code change, and thus is inappropriate for an update release. The fix is under review for push to JDK9.
16-06-2014

I think this is on Robert's area
04-06-2014

Probably related to JDK-8037404
04-06-2014

This isn't a hotspot issue: java.lang.invoke.LambdaConversionException: Type mismatch in captured lambda parameter 0: expecting class Test$2, found class Test This is either a user-error or else a javac issue with compiling the lambda expression. Assigning to tools->javac and marking with label "lambda"
04-06-2014