JDK-8194998 : broken error message for subclass of interface with private method
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9.0.4,10
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2018-01-11
  • Updated: 2018-06-01
  • Resolved: 2018-05-11
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 11
11 b14Fixed
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
17.2.0 Darwin Kernel Version 17.2.0: Fri Sep 29 18:27:05 PDT 2017; root:xnu-4570.20.62~3/RELEASE_X86_64 x86_64


A DESCRIPTION OF THE PROBLEM :
The following code is quite confusing, as after casting an anonymous class to its interface it can work as a functional interface (in various constructions actually):

public class A {
    public static void main(String[] args) {
        Runnable test1 = ((I)(new I() {}))::test;  // compiles OK
        Runnable test2 = ((new I() {}))::test;     // won't compile 
    }

    interface I {
        private void test() {}
    }
}

So,  Runnable test1 = ((I)(new I() {}))::test; compiles and works okay, while Runnable test2 = ((new I() {}))::test; doesn't compile.

It seems that it is not a consistent behavior.  Either one should be compiled well and another, or both shouldn't be compiled. 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the following code:

public class A {

    public static void main(String[] args) {
        Runnable test1 = ((I)(new I() {}))::test;
        Runnable test2 = ((new I() {}))::test;
    }

    interface I {
        private void test() {}
    }

}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Perhaps, Runnable test2 = ((new I() {}))::test; should be compiled fine in this example.
ACTUAL -
Runnable test1 = ((I)(new I() {}))::test; is compiled well
Runnable test2 = ((new I() {}))::test; is not compiled.



REPRODUCIBILITY :
This bug can be reproduced always.


Comments
evaluation from Maurizio: new I() {} doesn't have same members as I, the latter has a 'test' method but, since test is private it is not inherited by a subclass so the compiler is right in rejecting new I() {}::test but the diagnostic is wrong
12-01-2018

9.0.4 GA - Fail 10 ea b37 - Fail Result on 10 ea b37 == -sh-4.2$ /scratch/fairoz/JAVA/jdk10/jdk-10-ea+37/bin/javac A.java A.java:4: error: invalid method reference Runnable test2 = ((new I() {}))::test; // won't compile ^ compiler message file broken: key=compiler.misc.cant.resolve.args arguments=method, test, , , {4}, {5}, {6}, {7} 1 error ==
12-01-2018

Inconsistency in compiler error message started from "JDK-8071453: Allow interface methods to be private" This issue is similar to one we have observed in "JDK-8194847: javac generates bad code for private method in interface super call"
12-01-2018