netbeans
netbeans copied to clipboard
Fails to parse a file with incomplete switch expression
Apache NetBeans version
Apache NetBeans 16
What happened
When I add a case with a block to the switch expression, exception notification appears and completion stops working. If I try to save a file after that the whole application freezes.
How to reproduce
Suppose I have a class (requires JDK 17 with preview features enabled)
class Switch {
public boolean test(Object value) {
return switch (value) {
default -> false;
}
}
}
Then I start adding a new case. The issue happens right after I type the opening brace
class Switch {
public boolean test(Object value) {
return switch (value) {
case Boolean b -> { // <- this line added
default -> false;
}
}
}
Creating file with that contents does not always cause the issue but typing the line in editor always does. This also happened in previous versions of NetBeans and with previous JDK versions.
Did this work correctly in an earlier version?
No / Don't know
Operating System
Ubuntu Linux 22.04 amd64
JDK
OpenJDK 19 (system provided)
Apache NetBeans packaging
Apache NetBeans provided installer
Anything else
Stack trace reported by NetBeans
Caused: java.lang.NullPointerException: Cannot read field "type" because "tree" is null
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanCond(Flow.java:2145)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitYield(Flow.java:2785)
at com.sun.tools.javac.tree.JCTree$JCYield.accept(JCTree.java:1660)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scanSyntheticBreak(Flow.java:459)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.handleSwitch(Flow.java:2597)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitSwitchExpression(Flow.java:2565)
at com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1382)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanExpr(Flow.java:2118)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitReturn(Flow.java:2818)
at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1711)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitBlock(Flow.java:2402)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1082)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitMethodDef(Flow.java:2305)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:912)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitClassDef(Flow.java:2243)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:810)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3031)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3013)
at com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:224)
at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1377)
at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1341)
at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:404)
at com.sun.tools.javac.api.JavacTaskImpl.lambda$analyze$1(JavacTaskImpl.java:379)
at com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:379)
Caused: java.lang.IllegalStateException
at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:383)
at org.netbeans.modules.java.source.parsing.JavacParser.moveToPhase(JavacParser.java:770)
at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:540)
at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:141)
at org.netbeans.modules.parsing.impl.TaskProcessor.callGetResult(TaskProcessor.java:608)
at org.netbeans.modules.parsing.impl.SourceCache.getResult(SourceCache.java:241)
at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.run(TaskProcessor.java:775)
at org.openide.util.lookup.Lookups.executeWith(Lookups.java:279)
at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.execute(TaskProcessor.java:702)
[catch] at org.netbeans.modules.parsing.impl.TaskProcessor$CompilationJob.run(TaskProcessor.java:663)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1418)
at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
at org.openide.util.lookup.Lookups.executeWith(Lookups.java:278)
at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2033)
Are you willing to submit a pull request?
No
Code of Conduct
Yes
any on-save action enabled? Organize imports or formatting etc?
Yes, "Remove unused imports". After disabling it I can save, so this is actually two separate issues.
right, just wanted to make sure this applies here too. The other issue is tracked under #4054.
Is this still a valid issue?
Yes, it's still a valid issue. I get exactly the same stack trace as SBasalaev. NetBeans 18 (binary from zip), Debian Bookworm (12.1), OpenJDK-17 (Debian supplied). LXDE desktop. Peter
i am wondering why issues like this don't show up when javac is ran from CLI. NPEs in javac seem to be more common now. Going to start using the https://github.com/apache/netbeans/labels/nb-javac label for issues like this. The good thing here is that we have a simple reproducer which other filed issues lack.
cc @lahodaj
checked and this is still reproducible with 22-rc1
updated trace since the line numbers moved:
Caused: java.lang.NullPointerException: Cannot read field "type" because "tree" is null
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanCond(Flow.java:2293)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitYield(Flow.java:2913)
at com.sun.tools.javac.tree.JCTree$JCYield.accept(JCTree.java:1677)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scanSyntheticBreak(Flow.java:475)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.handleSwitch(Flow.java:2725)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitSwitchExpression(Flow.java:2700)
at com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanExpr(Flow.java:2270)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitReturn(Flow.java:2946)
at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1728)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:58)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitBlock(Flow.java:2537)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1092)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitMethodDef(Flow.java:2440)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:916)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitClassDef(Flow.java:2384)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:814)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3174)
at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3156)
at com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:231)
at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1426)
at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1390)
at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:404)
at com.sun.tools.javac.api.JavacTaskImpl.lambda$analyze$1(JavacTaskImpl.java:379)
at com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:379)
Caused: java.lang.IllegalStateException
at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:383)
at org.netbeans.modules.java.source.parsing.JavacParser.moveToPhase(JavacParser.java:765)
at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:536)
at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:140)
at org.netbeans.modules.parsing.impl.TaskProcessor.callGetResult(TaskProcessor.java:608)
at org.netbeans.modules.parsing.impl.SourceCache.getResult(SourceCache.java:241)
at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.run(TaskProcessor.java:775)
at org.openide.util.lookup.Lookups.executeWith(Lookups.java:288)
at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.execute(TaskProcessor.java:702)
[catch] at org.netbeans.modules.parsing.impl.TaskProcessor$CompilationJob.run(TaskProcessor.java:663)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1420)
at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2035)
FWIW, I've filled: https://bugs.openjdk.org/browse/JDK-8331212 have a (potential) fix, will open a PR sometime soon.
the nb-javac update https://github.com/apache/netbeans/pull/7484 fixed this and is already testable in NB23rc1. There is no longer an exception and the errors are annotated as expected:
closing