JDK-8030816 : javac crashes when mixing lambdas and inner classes
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • Submitted: 2013-12-18
  • Updated: 2014-08-15
  • Resolved: 2014-01-27
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
8u20 b01Fixed 9Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
1.8.0-ea-b120

A DESCRIPTION OF THE PROBLEM :
javac can't compile the following program with a lambda expression:
-----
//import java.awt.event.*;
import javax.swing.*;

public class Test {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JButton button = new JButton("Test");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                }
            });
            frame.add(button);
            frame.setSize(160, 160);
            frame.setVisible(true);
        });
    }
}
-----


ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitMethodDef(Flow.java:497)
        at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:772)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:389)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitClassDef(Flow.java:475)
        at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:687)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:389)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitNewClass(Flow.java:702)
        at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1510)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:389)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitApply(Flow.java:695)
        at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1459)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:389)
        at com.sun.tools.javac.tree.TreeScanner.visitExec(TreeScanner.java:175)
        at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1290)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:389)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.scanStat(Flow.java:433)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.scanStats(Flow.java:441)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitBlock(Flow.java:525)
        at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:903)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:389)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.scanStat(Flow.java:433)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.visitLambda(Flow.java:718)
        at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1618)
        at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
        at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:389)
        at com.sun.tools.javac.comp.Flow$AliveAnalyzer.analyzeTree(Flow.java:746)
        at com.sun.tools.javac.comp.Flow.analyzeLambda(Flow.java:226)
        at com.sun.tools.javac.comp.Attr.visitLambda(Attr.java:2393)
        at com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1618)
        at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:596)
        at com.sun.tools.javac.comp.DeferredAttr.attribSpeculative(DeferredAttr.java:372)
        at com.sun.tools.javac.comp.DeferredAttr$2.complete(DeferredAttr.java:265)
        at com.sun.tools.javac.comp.DeferredAttr$DeferredType.check(DeferredAttr.java:231)
        at com.sun.tools.javac.comp.DeferredAttr$DeferredType.check(DeferredAttr.java:218)
        at com.sun.tools.javac.comp.Resolve$MethodResultInfo.check(Resolve.java:976)
        at com.sun.tools.javac.comp.Resolve$4.checkArg(Resolve.java:822)
        at com.sun.tools.javac.comp.Resolve$AbstractMethodCheck.argumentsAcceptable(Resolve.java:733)
        at com.sun.tools.javac.comp.Resolve$4.argumentsAcceptable(Resolve.java:831)
        at com.sun.tools.javac.comp.Resolve.rawInstantiate(Resolve.java:578)
        at com.sun.tools.javac.comp.Resolve.selectBest(Resolve.java:1418)
        at com.sun.tools.javac.comp.Resolve.findMethodInScope(Resolve.java:1597)
        at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:1668)
        at com.sun.tools.javac.comp.Resolve.findMethod(Resolve.java:1641)
        at com.sun.tools.javac.comp.Resolve$9.doLookup(Resolve.java:2397)
        at com.sun.tools.javac.comp.Resolve$BasicLookupHelper.lookup(Resolve.java:3056)
        at com.sun.tools.javac.comp.Resolve.lookupMethod(Resolve.java:3307)
        at com.sun.tools.javac.comp.Resolve.resolveQualifiedMethod(Resolve.java:2394)
        at com.sun.tools.javac.comp.Resolve.resolveQualifiedMethod(Resolve.java:2388)
        at com.sun.tools.javac.comp.Attr.selectSym(Attr.java:3317)
        at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3211)
        at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1891)
        at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:596)
        at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1828)
        at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1459)
        at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:596)
        at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:645)
        at com.sun.tools.javac.comp.Attr.visitExec(Attr.java:1596)
        at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1290)
        at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:596)
        at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:665)
        at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:681)
        at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1127)
        at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:903)
        at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:596)
        at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:665)
        at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1020)
        at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:772)
        at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:596)
        at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:665)
        at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4259)
        at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4169)
        at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4103)
        at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4078)
        at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1251)
        at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:904)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:863)
        at com.sun.tools.javac.main.Main.compile(Main.java:523)
        at com.sun.tools.javac.main.Main.compile(Main.java:381)
        at com.sun.tools.javac.main.Main.compile(Main.java:370)
        at com.sun.tools.javac.main.Main.compile(Main.java:361)
        at com.sun.tools.javac.Main.compile(Main.java:56)
        at com.sun.tools.javac.Main.main(Main.java:42)

REPRODUCIBILITY :
This bug can be reproduced always.
Comments
Verified
29-07-2014

Release notes proposal: Before this release, this sample code: class LambdaExpressionWithNonExistentIdCrashesJavacTest { void foo() { bar(()-> { new NonExistentClass(){ public void any() {} }; }); } void bar(Runnable r) {} } was making the compiler fail with a NPE. This is the minimal test case but a similar failure was detected for cases where the NonExistentClass was a real but inaccessible class. This issue is now fixed in the compiler. After the fix, javac is producing an error message indicating that symbol "NonExistentClass" can't be found. Please note that this is a corner case as method any() doesn't exist either.
28-07-2014

ILW=HHL -> P2
10-03-2014

ILW classification: Impact = H (crash) Likelihood = H (this code seems to be very frequent for visual applications) Workaround = L (don't use lambdas) (HHL) => P2 updating the priority to P2
10-03-2014

Release team: We're glad you feel so strongly about this issue. We reviewed it again but deem it's not critical to fix so our earlier decision stands.
16-01-2014

Minimal test case: public class Test { void m() { m1(()-> { new A(){ public void m11() {} }; }); } void m1(Runnable r) {} }
03-01-2014

I was able to reproduce it with latest 1.8.0-ea-b121.
19-12-2013