NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.39k stars 13.61k forks source link

jdt-language-server fails to initialize Gradle workspace #297180

Open ony opened 6 months ago

ony commented 6 months ago

Describe the bug

jdt-language-server is not fully usable in NixOS 23.11 as Gradle fails due to Java version incompatibility.

Eclipse JDT language server configured to use jdk

https://github.com/NixOS/nixpkgs/blob/79baff8812a0d68e24a836df0a364c678089e2c7/pkgs/development/tools/language-servers/jdt-language-server/default.nix#L5

And it is by default jdk19 as per

https://github.com/NixOS/nixpkgs/blob/79baff8812a0d68e24a836df0a364c678089e2c7/pkgs/top-level/all-packages.nix#L16469

And there are no overrides for jdt-language-server in top-level/all-packages.nix

https://github.com/NixOS/nixpkgs/blob/79baff8812a0d68e24a836df0a364c678089e2c7/pkgs/top-level/all-packages.nix#L18377

Steps To Reproduce

Steps to reproduce the behavior:

  1. Using home-manager try to configure nvim-jdtls
    programs.neovim.plugins = with pkgs.vimPlugins; [
      nvim-jdtls  # rest configuration in ftplugin/java.lua
    ];
    home.packages = with pkgs; [ jdk gradle jdt-language-server ];
    -- ftplugin/java.lua
    local config = {
      cmd = {
        'jdt-language-server',
        "-configuration", vim.fn.expand("$HOME/.cache/jdtls/config"),
        "-data", vim.fn.expand("$HOME/.cache/jdtls/workspace"),
      },
      root_dir = vim.fs.dirname(vim.fs.find({'gradlew', '.git', 'mvnw'}, { upward = true })[1]),
    }
    require('jdtls').start_or_attach(config)
  2. Clear Gradle and JDT cache to ensure previous setup is not interfering. E.g. rm -rvf ~/.cache/jdtls ~/.gradle.
  3. Open some simple Java file and wait for a bit. For me last message shown was "80% Starting Java Language Server".
  4. Check logs via :JdtShowLogs
  5. In opened ~/.cache/jdtls/workspace/.metadata/.log notice errors
!MESSAGE Importing Gradle project(s)
...
!MESSAGE Initialization failed 
!STACK 0
org.eclipse.core.runtime.AssertionFailedException: assertion failed: Marker property value is too long: org.gradle.tooling.BuildActionFailureException: The supplied phased action failed with an exception.
    at org.gradle.tooling.internal.consumer.connection.PhasedActionAwareConsumerConnection.run(PhasedActionAwareConsumerConnection.java:58)
    at org.gradle.tooling.internal.consumer.connection.ParameterValidatingConsumerConnection.run(ParameterValidatingConsumerConnection.java:62)
    at org.gradle.tooling.internal.consumer.DefaultPhasedBuildActionExecuter$1.run(DefaultPhasedBuildActionExecuter.java:78)
...
!MESSAGE Error occured while building workspace. Details: 
 message: The supplied phased action failed with an exception.
Could not open init generic class cache for initialization script '/home/mykola/.cache/jdtls/config/org.eclipse.osgi/51/0/.cp/gradle/init/init.gradle' (/home/mykola/.gradle/caches/7.4.2/scripts/7s4n1zerenary6wu67e7f3xej).
Could not compile initialization script '/home/mykola/.cache/jdtls/config/org.eclipse.osgi/51/0/.cp/gradle/init/init.gradle'.
startup failed:
General error during conversion: Unsupported class file major version 63
java.lang.IllegalArgumentException: Unsupported class file major version 63
    at groovyjarjarasm.asm.ClassReader.<init>(ClassReader.java:199)
...

Note that major version 63 corresponds to Java 19.

Expected behavior

A clear and concise description of what you expected to happen.

...
!MESSAGE Initializing Java Language Server 1.26.0.202307271613
...
!MESSAGE Importing Gradle project(s)
...
!MESSAGE Workspace initialized in 4098ms
...

(no errors)

Additional context

Overriding jdk to use jdk17 (matching Gradle version) makes it work

        # Gradle only supports JDK 8/11/17
        # switching versions may require: rm -rf ~/.cache/jdtls ~/.gradle
        (jdt-language-server.override { jdk = jdk17; })

Notify maintainers

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

nix shell nixpkgs\#nix-info --command nix-info -m

Latest update of nixpkgs for home manger: 79baff8812a0d68e24a836df0a364c678089e2c7 2024-03-01T17:18:46 CET


Add a :+1: reaction to issues you find important.

TomaSajt commented 5 months ago

In the README.md it says that it "Supports compiling projects from Java 1.5 through 19", so the best thing to do for now, as you just did, is to pin the jdk version to jdk17. I'll open a PR

matt-snider commented 5 months ago

@TomaSajt From the eclipse.jdt.ls README, as you noted it says

Supports compiling projects from Java 1.5 through 19

However this isn't any indication of what version the JDK running jdt.ls needs to be. That is mentioned further down under "Requirements":

The language server requires a runtime environment of Java 17 (at a minimum) to run

So Java 19 should work fine.

Unsupported class file major version 63

@ony As you noted, you are using Gradle 7.4.2 which only only supports up to JDK 17. Gradle 7.6 adds support for JDK 19.

So the problem here isn't that the package should be using JDK 17, it's that the runtime is impure because it uses the environment (in your case /home/mykola/.gradle/caches/7.4.2/...) instead of a fixed gradle version.

@TomaSajt I think the right approach here would be to modify this package to ensure jdk19 is used (not jdk because then it will break as soon as jdk points to v21) and the ensure the right Gradle version is being used.

I'm going to comment in your PR #297556 with more thoughts.

TomaSajt commented 5 months ago

Thanks for the reply, and by the way, AFAICT, jdk already points to jdk21

matt-snider commented 5 months ago

@ony I think you are not actually using the current jdt.ls package. I see that because you are executing jdt-language-server and this changed in PR #279285. So actually, the PR from @TomaSajt cannot address your issue unless you upgrade.

I think you can use your workaround with the override to jdk17 for now, and eventually, after the PR is merged, update to the new version.

ony commented 5 months ago

As you noted, you are using Gradle 7.4.2 which only only supports up to JDK 17. Gradle 7.6 adds support for JDK 19.

So the problem here isn't that the package should be using JDK 17, it's that the runtime is impure because it uses the environment (in your case /home/mykola/.gradle/caches/7.4.2/...) instead of a fixed gradle version.

@matt-snider , sorry for late follow-up. Honestly, I was not sure why folder name is 7.4.2. gradle (that I mentioned) for nixos-23.11 (at least revision I'm on) uses 8.4.
But after checking I think it is just bundled with Eclipse JDT

zsh% find /nix/store/15dvj1sywr30z2j9ffdh07kgy75jr010-jdt-language-server-1.26.0 | rg gradle
/nix/store/15dvj1sywr30z2j9ffdh07kgy75jr010-jdt-language-server-1.26.0/share/java/plugins/org.gradle.toolingapi_7.4.2.v20220712-0930-s.jar

I think you are not actually using the current jdt.ls package. I see that because you are executing jdt-language-server and this changed in PR #279285. So actually, the PR from @TomaSajt cannot address your issue unless you upgrade.

Yes. Thank you. I just faced some other issues during upgrade to more recent revision that I need to look into.

With this issue I mostly wanted to share my findings about the fact that use of jdk with Eclipse JDT without any other modifications may suffer from reducing functionality. Pinning dependency is only one thought I came up with.