scalameta / metals

Scala language server with rich IDE features 🚀

Home Page:https://scalameta.org/metals/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

semanticdb, the silent killer

tballard opened this issue · comments

Describe the bug

I was trying metals, again, since intellij was acting up. I got a problem pretty quickly. It sounds the same as #6033, only it's "javac", not "java". Compilation fails. The position of the error (error: semanticdb-javac: bloop ) is on the "package" line of a seemingly arbitrary java file that has compiled fine for 5 years.

I'm using the mill build tool.

Looking at bloop.settings.json, the supported scala versions only go to 2.13.12, whereas I'm using 3.3.3, but it seems a lot happier than I would expect if that was relevant.

I haven't gotten far enough to test it, but previously setting the working directory in the run config was impossible in metals but not in vs-code in general. It was a breaker for me, but it's hard to imagine it's anything but a trivial fix.

Expected behavior

Seeing as it compiles fine, compiling fine was my hope. "Expected" might be a little strong.

Operating system

macOS

Editor/Extension

VS Code

Version of Metals

v1.29.0

Extra context or search terms

No response

Thanks for the report. This does look like a problem with Java semanticdb compiler plugin. Would you be able to provide a reproduction of the issue? You could also try switching the build server to mill instead of bloop to make sure it's not a bloop specific issue.

Hi there, I can join the club.

While updating an old project I got slammed by the semanticdb-javac: error.
It indeed looks like Javac plugin dies and it tries to spit out an error, but it doesn't get further than an empty string.

The project was coming from a bloop 1.4.4 era, but if I tested different bloop versions I see it now breaks as of bloop 1.4.10.
Which is all about scalacenter/bloop#1534.
Though that is probably somewhat misleading. It seems like Metals or Bloop are very eager to use the latest version of Java Semantic DB.

.bloop/bloop.settings.json

    "javaSemanticDBVersion": "0.9.9",

Which I believe equates to: https://central.sonatype.com/artifact/com.sourcegraph/semanticdb-javac/0.9.9
That allowed me to play with the version of that thing.

  1. Removing the setting entirely, which disables Java Semantic DB , "fixes" it.
  2. Downgrading to version 0.9.3 also fixes the problem.
    "javaSemanticDBVersion": "0.9.3",

So it looks like it went sour in:

A 65 file PR, I can see how something could go a bit haywire 😨
I should probably not that this is running against a Java 8 JDK. That might matter?

What I haven't figured out is what rewrites that .bloop/bloop.settings.json. If you restart bloop with bloop CLI, it seems to stay unmodified, but if I restart using VSCode metals it seems get set back to v0.9.9.

So this is what I got out of it.

It seems to be triggered by an annotation on a local variable

  private <T> Function<InvocationHandler, T> getConstructor(Class<T> contract) {
    @SuppressWarnings("unchecked")
    Constructor<T> constructor = (Constructor<T>) 

Which throws a NullPointerException here

JavacTrees.getElement(TreePath) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\api\JavacTrees.java:319)
JavacTrees.getElement(TreePath) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\api\JavacTrees.java:119)
SemanticdbTrees.annotationBuilder(AnnotationTree) (Unknown Source:87)
SemanticdbTrees.annotations(Tree) (Unknown Source:71)
SemanticdbVisitor.emitSymbolInformation(Element,Tree) (Unknown Source:134)
SemanticdbVisitor.emitSymbolOccurrence(Element,Tree,Name,Semanticdb$SymbolOccurrence$Role,CompilerRange) (Unknown Source:114)
SemanticdbVisitor.resolveVariableTree(VariableTree,TreePath) (Unknown Source:282)
SemanticdbVisitor.resolveNodes() (Unknown Source:209)
SemanticdbVisitor.buildTextDocument(CompilationUnitTree) (Unknown Source:94)
SemanticdbTaskListener.onFinishedAnalyze(TaskEvent) (Unknown Source:96)
SemanticdbTaskListener.finished(TaskEvent) (Unknown Source:63)
ClientCodeWrapper$WrappedTaskListener.finished(TaskEvent) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\api\ClientCodeWrapper.java:681)
MultiTaskListener.finished(TaskEvent) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\api\MultiTaskListener.java:111)
JavaCompiler.flow(Env,Queue) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\main\JavaCompiler.java:1342)
JavaCompiler.flow(Env) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\main\JavaCompiler.java:1296)
JavaCompiler.compile2() (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\main\JavaCompiler.java:901)
JavaCompiler.compile(List,List,Iterable) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\main\JavaCompiler.java:860)
Main.compile(String[],String[],Context,List,Iterable) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\main\Main.java:523)
Main.compile(String[],Context,List,Iterable) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\main\Main.java:381)
Main.compile(String[],Context) (c:\Program Files\Java\graalvm-ce-java8-20.3.3\src\com\sun\tools\javac\main\Main.java:370)

Because here
https://github.com/sourcegraph/scip-java/blob/e4c4ffb42e11cf8bab94e8d038c42f939e6b3d27/semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbTrees.java#L87

variableTreePath ends up being null.

For some reason this new construct cannot cope with annotations on local variables. If I move the annotation to the method level it seems to get past the null pointer problem. I also have another java codebase where I use it on fields or classes where I didn't see the issue surface.

More I wasn't able to determine whilst debugging on the release version of the Javac plugin.

Why it fails on that exact instance is unclear, because I have other occurrences of annotations on local variables that don't make the plugin trip.

Even with the snipped provided I cannot reproduce this issue but checking for a null can't hurt.

Thanks for creating the reproduction that and generally taking the time to dig into this problem. With the reproduction it should be much easier to fix the issue.