JDK-8143647 : Javac compiles method reference that allows results in an IllegalAccessError
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-06-06
  • Updated: 2016-07-21
  • Resolved: 2015-11-26
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
8u102Fixed 9 b96Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
Javac shouldn't allow referencing a method that is out of scope.  Either it should produce a compile-time error or it should desugar as in the lambda equivalent.





STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Create default-scoped abstract class with concrete method
2) Create a concrete public class extending the above class in the same package
3) Use a method reference to this inherited method in a class outside of the package

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Either
A) compiles the same as map(y -> y.getX())
B) compile-time error
ACTUAL -
IllegalAccessError at runtime

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package x;
abstract class X {
public String getX() { return "x";}

package x;
public class Y extends X {}

package z;
public class Z {
public static void main (String[] args) {
  Arrays.asList(new Y()).stream().map(Y::getX).forEach(System.out::println);
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Use lambda form


Comments
This problem can be seen to be a one particular instance of the general problem captured in https://bugs.openjdk.java.net/browse/JDK-8059632 I am exploring providing a (complete, but) point fix for the present ticket. More general solution should be explored in the context of https://bugs.openjdk.java.net/browse/JDK-8059632
24-11-2015

Eclipse compiles both the lines properly and gives the expected output. Both lines actually does the same work, But issue is with command prompt line1 gives IllegalAccessError at runtime, where as line2 compiles and runs properly. public static void main (String[] args) { Arrays.asList(new Y()).stream().map(Y::getX).forEach(System.out::println); // line 1 problem //Arrays.asList(new Y()).stream().map(y->y.getX()).forEach(System.out::println); //line 2 no problem } } Executed with command prompt produces different results D:\2015\work\JI\src>"c:\Program Files\Java\jdk1.9.0\bin\javac.exe" z/Z.java D:\2015\work\JI\src>"c:\Program Files\Java\jdk1.9.0\bin\java.exe" z.Z Exception in thread "main" java.lang.IllegalAccessError: tried to access class JI9021589.X from class z.Z at z.Z.lambda$main$0(Z.java:9) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:430) at z.Z.main(Z.java:9) Verified with below builds 1.8.0 - Fail 8u45 - Fail 8u60 - Fail 8u65 - Fail 8u72 - Fail (It looks like it exist in all the versions of 8, but verified only few ) 9 ea - Fail
23-11-2015