zed
zed copied to clipboard
Add Java language support
Release Notes:
- Add Java language support #5301 .
Added eclipse.jdtls lsp server with Lombok plugin for Java. https://streamable.com/0cqa07
However, The Java support still has two main problems:
- We are unable to navigate to the definition in the source code (basically .class files).
- Quick actions do not work, likely due to unsupported types of code actions.
I would appreciate suggestions on how to solve these issues, as I have not found a way to do so.
PR is co-authored with @valentinegb
re: quick actions, I think https://github.com/zed-industries/zed/pull/8874 could be the culprit. Could you try resolving the actions always here https://github.com/zed-industries/zed/blob/fae5e83d93c9dfc794e0d80e4f9df95b78a576b8/crates/project/src/project.rs#L5415-L5426 and see if that fixes things for you?
Hey! It's been a little bit since I contributed to this, sorry about that. The absence of functions is actually one of the last things I was working on, I was struggling a bit though because the Java Tree-sitter is a little different than the other Tree-sitters we use and doesn't make it easy to get info from a function declaration, iirc it doesn't have any fields and uses few non-hidden rules, but I'll be looking into that again soon.
Also, since I noticed that @ABckh has been merging and I would usually rebase, what's the preferred conflict resolution method in this repository?
Also, since I noticed that @ABckh has been merging and I would usually rebase, what's the preferred conflict resolution method in this repository?
I'm just a rando watching you guys work, but ever other PR I've seen has been rebased. The devs will usually request a rebase before a PR is merged.
Also, since I noticed that @ABckh has been merging and I would usually rebase, what's the preferred conflict resolution method in this repository?
We squash merge all PRs going into main
, so it doesn't matter what you use on the branch itself. I generally use merge commits on branches.
Sorry, I am no good with tree-sitter queries, but maybe @maxbrunsfeld can check that out?
I have also tried running the same branch locally in better network conditions, ~10x faster internet and, separately, on mobile internet — all 3 times I have the same
[2024-03-05T22:33:48+02:00 ERROR project] server stderr: Some("Traceback (most recent call last):\n File \"/Users/someonetoignore/Library/Application Support/Zed/languages/eclipse.jdt.ls/bin/jdtls\", line 17, in <module>\n jdtls.main(sys.argv[1:])\n File \"/Users/someonetoignore/Library/Application Support/Zed/languages/eclipse.jdt.ls/bin/jdtls.py\", line 78, in main\n java_executable = get_java_executable(known_args.validate_java_version)\n File \"/Users/someonetoignore/Library/Application Support/Zed/languages/eclipse.jdt.ls/bin/jdtls.py\", line 33, in get_java_executable\n out = subprocess.check_output([java_executable, '-version'], stderr = subprocess.STDOUT, universal_newlines=True)\n File \"/Users/someonetoignore/.pyenv/versions/3.9.16/lib/python3.9/subprocess.py\", line 424, in check_output\n return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,\n File \"/Users/someonetoignore/.pyenv/versions/3.9.16/lib/python3.9/subprocess.py\", line 528, in run\n raise CalledProcessError(retcode, process.args,\nsubprocess.CalledProcessError: Command '['java', '-version']' returned non-zero exit status 1.\n")
I suspect something is fundamentally broken with the fetching, and would recommend moving away the java language servers out of ~/Library/Application Support/Zed/languages/
to reproduce the issue locally.
Oh, looks like queries are much better — can see the methods and even constructors now.
One optional note on top: Intellij seems to also include constants into outlines, we could do that too:
but that is small compared to methods added.
Sorry, I am no good with tree-sitter queries, but maybe @maxbrunsfeld can check that out?
I have also tried running the same branch locally in better network conditions, ~10x faster internet and, separately, on mobile internet — all 3 times I have the same
[2024-03-05T22:33:48+02:00 ERROR project] server stderr: Some("Traceback (most recent call last):\n File \"/Users/someonetoignore/Library/Application Support/Zed/languages/eclipse.jdt.ls/bin/jdtls\", line 17, in <module>\n jdtls.main(sys.argv[1:])\n File \"/Users/someonetoignore/Library/Application Support/Zed/languages/eclipse.jdt.ls/bin/jdtls.py\", line 78, in main\n java_executable = get_java_executable(known_args.validate_java_version)\n File \"/Users/someonetoignore/Library/Application Support/Zed/languages/eclipse.jdt.ls/bin/jdtls.py\", line 33, in get_java_executable\n out = subprocess.check_output([java_executable, '-version'], stderr = subprocess.STDOUT, universal_newlines=True)\n File \"/Users/someonetoignore/.pyenv/versions/3.9.16/lib/python3.9/subprocess.py\", line 424, in check_output\n return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,\n File \"/Users/someonetoignore/.pyenv/versions/3.9.16/lib/python3.9/subprocess.py\", line 528, in run\n raise CalledProcessError(retcode, process.args,\nsubprocess.CalledProcessError: Command '['java', '-version']' returned non-zero exit status 1.\n")
I suspect something is fundamentally broken with the fetching, and would recommend moving away the java language servers out of
~/Library/Application Support/Zed/languages/
to reproduce the issue locally.
Hello, this is super interesting, as I have not experienced it locally. Seems that it cannot find java at all, maybe it could happen cause you do not have JAVA_HOME set, but I will investigate further, thank you for your feedback.
Also found very bad issue, when we open problems of the project with lots of warnings/errors it just freezes zed for several seconds with loading spinner
Thank you for the pointers — it was indeed a malformed JAVA_HOME value, it did download the server after fixing it, but we'd rather mention that in the docs (that we're supposed to add here), I think.
Also, it looks like that Java-based server is quite slow to start, and it sends a lot of language/status
notifications with the startup percentage:
[2024-03-05T23:05:29+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status:
{
"type": "Starting",
"message": "31% Starting Java Language Server - Refreshing '/jdt.ls-java-project'."
}
....
[2024-03-05T23:07:22+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status:
{
"type": "Starting",
"message": "80% Starting Java Language Server - Download https://repo.gradle.org/gradle/list/libs-releases/org/codehaus/groovy/groovy-templates/3.0.17/groovy-templates-3.0.17.pom"
}
[2024-03-05T23:07:23+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status:
{
"type": "Starting",
"message": "80% Starting Java Language Server - Download https://repo.gradle.org/gradle/list/libs-releases/org/codehaus/groovy/groovy-test/3.0.17/groovy-test-3.0.17.pom"
}
[2024-03-05T23:07:23+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status:
{
"type": "Starting",
"message": "80% Starting Java Language Server - Build model 'org.gradle.tooling.model.eclipse.RunClosedProjectBuildDependencies' for root project 'flow-gradle-plugin'"
}
...
[2024-03-05T23:11:06+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/eventNotification:
{
"eventType": 100,
"data": "file:/Users/someonetoignore/Downloads/flow/flow-plugins/flow-gradle-plugin/"
}
....
That https://github.com/vaadin/flow/ is very slow to index for me, if you notice the timestamps.
We have a mechanism to track and render that for spec-compliant servers: https://github.com/zed-industries/zed/blob/a90e6b07ee6195799e59692a6293391ac0d2696d/crates/project/src/project.rs#L3608
And looks like this server sends that info too
but apparently that custom notification set has to go into the same reporting code in zed, since ~10 mins of load wait with 0 indication looks very extreme. It's a first start though, with zero dependencies in the maven cache, maybe that's the reason.
I am not sure what to suggest to the notification perf issues, maybe it's something external to Java langserver per se, but interesting to see what is slow there indeed.
Seems that Java will push Zed to the limit on that front too, here's what I see in flow
project:
and seems like we need to start thinking on diagnostics ergonomics again.
Otherwise, looks like rename and formatting capabilities work somehow, albeit that LSP server formats things differently compared to flow guidelines.
Thank you for the pointers — it was indeed a malformed JAVA_HOME value, it did download the server after fixing it, but we'd rather mention that in the docs (that we're supposed to add here), I think.
Also, it looks like that Java-based server is quite slow to start, and it sends a lot of
language/status
notifications with the startup percentage:[2024-03-05T23:05:29+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status: { "type": "Starting", "message": "31% Starting Java Language Server - Refreshing '/jdt.ls-java-project'." } .... [2024-03-05T23:07:22+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status: { "type": "Starting", "message": "80% Starting Java Language Server - Download https://repo.gradle.org/gradle/list/libs-releases/org/codehaus/groovy/groovy-templates/3.0.17/groovy-templates-3.0.17.pom" } [2024-03-05T23:07:23+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status: { "type": "Starting", "message": "80% Starting Java Language Server - Download https://repo.gradle.org/gradle/list/libs-releases/org/codehaus/groovy/groovy-test/3.0.17/groovy-test-3.0.17.pom" } [2024-03-05T23:07:23+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/status: { "type": "Starting", "message": "80% Starting Java Language Server - Build model 'org.gradle.tooling.model.eclipse.RunClosedProjectBuildDependencies' for root project 'flow-gradle-plugin'" } ... [2024-03-05T23:11:06+02:00 INFO lsp] Language server with id 1 sent unhandled notification language/eventNotification: { "eventType": 100, "data": "file:/Users/someonetoignore/Downloads/flow/flow-plugins/flow-gradle-plugin/" } ....
That https://github.com/vaadin/flow/ is very slow to index for me, if you notice the timestamps.
We have a mechanism to track and render that for spec-compliant servers:
https://github.com/zed-industries/zed/blob/a90e6b07ee6195799e59692a6293391ac0d2696d/crates/project/src/project.rs#L3608
And looks like this server sends that info too
but apparently that custom notification set has to go into the same reporting code in zed, since ~10 mins of load wait with 0 indication looks very extreme. It's a first start though, with zero dependencies in the maven cache, maybe that's the reason.
I am not sure what to suggest to the notification perf issues, maybe it's something external to Java langserver per se, but interesting to see what is slow there indeed. Seems that Java will push Zed to the limit on that front too, here's what I see in
flow
project:and seems like we need to start thinking on diagnostics ergonomics again.
Otherwise, looks like rename and formatting capabilities work somehow, albeit that LSP server formats things differently compared to flow guidelines.
Thank you for feedback! Yes, it is not okay to have project loaded for 10 minutes even for the first time, I am currently investigating on how can we improve the performance of jdtls, as for now it is using wrapper script to run LSP server with almost default configs (lombok is added and log level is reduced) (https://github.com/ABckh/eclipse.jdt.ls), so I will try to adjust it, but anyways it can be that it is just java 🙃
Regarding formatting of the code, have just compared Intellij and VSCode (which also uses eclipse.jdt.ls), it seems like VSCode has different indents level, so I will take a look if we can make it configurable with jdtls. Also, totally agree that we should add prerequisites to docs
Should we set this PR to be a draft PR since it's still in progress? (I am unable to myself.)
it was indeed a malformed JAVA_HOME value, it did download the server after fixing it, but we'd rather mention that in the docs (that we're supposed to add here), I think.
I had just starting writing the docs for this, but then I checked my JAVA_HOME
and noticed it was empty. I checked PATH
too and that, at least not directly, doesn't contain a path to any JDK either. Despite this though the language server works just fine on my machine. (I do, of course, have a JDK installed).
I noticed these debug messages:
Could this be related to problem number 1?
We are unable to navigate to the definition in the source code (basically .class files).
Looks like it, and speaking of the actions issue, the fix is in main
speaking of the actions issue, the fix is in
main
Oh fantastic, I'll rebase next time I'm on my computer!
Language server adapters can now be provided in language extensions. There is currently a Java extension (which does not provide LSP support yet), implemented by this repo: https://github.com/louisnicolas-longheval-vinci/zed-java-extension/tree/main/languages/java.
@louisnicolas-longheval-vinci @ABckh Could you two collaborate to add LSP support to the existing extension?
Language server adapters can now be provided in language extensions. There is currently a Java extension (which does not provide LSP support yet), implemented by this repo: https://github.com/louisnicolas-longheval-vinci/zed-java-extension/tree/main/languages/java.
@louisnicolas-longheval-vinci @ABckh Could you two collaborate to add LSP support to the existing extension?
Hello! of course, but as mentioned here at the moment I don't really have the time. that said, I'm open to conversation.
@louisnicolas-longheval-vinci if you want, we can transfer the repo to the zed-extensions
org, so that you don't have to manage it. If we do that, I'd be fine with having both you and @ABckh as maintainers, as well us some of the Zed team.
@maxbrunsfeld yes that would be nice for everyone i think.
@louisnicolas-longheval-vinci if you want, we can transfer the repo to the
zed-extensions
org, so that you don't have to manage it. If we do that, I'd be fine with having both you and @ABckh as maintainers, as well us some of the Zed team.
Hello, @maxbrunsfeld and @louisnicolas-longheval-vinci It would be great to do that, than we can close this PR and move the changes to specific Java plugin repo. I have not worked on this feature for a while, but when I was working on LSP support there were some issues:
- Performance issues of eclipse jdtls LSP
- When a project is large and it has lots of warnings diagnostics tab is super laggy
- Code actions did not work, but as I understood it was fixed already, but I have not checked yet
After these issues will be solved, hopefully we can start use Java in Zed! I will have a bit more free time and will contribute to it
bumping this because I love zed and also java. it would be really nice to use my main language on zed. :)
Closing this PR because of the newly added Java Eclipse JDTLS extension