Skip to content

bug: jdtls is not using jdk-21 #204

Closed

Description

@kyerpotts

Did you check docs and existing issues?

  • I have read all the plugin docs
  • I have searched the existing issues
  • I have searched the existing issues of plugins related to this issue

Neovim version (nvim -v)

0.10.0 release

Operating system/version

Arch Linux

Describe the bug

My default version of Java is 21, and I have set the default java path in lspconfig to the binary. When I attempt to run or debug, I receive an UnsupportedClassVersionError. I believe this is because openjdk-17 is hardcoded into the nvim-java plugin for builds, however it uses the specified runtime binary configured by lspconfig. I have resolved the issue by setting my default java runtime version to 17 and updating the required path, however it would be useful to be able to change the javac version as a config for the nvim-java in order to avoid ClassVersionErrors.

Steps To Reproduce

  1. Install java 21 using sdkman
  2. Set up nvim-java
  3. set up mason, mason-lspconfig and lspconfig.
  4. setup jdtls using lspconfig.
    require("lspconfig").jdtls.setup({ settings = { java = { configuration = { runtimes = { { name = "JavaSE-21", path ="/PATH/TO/JAVA/RUNTIME/21", default = true, }, }, },
  5. Run debugger / JavaRunnerRunMain

Expected Behavior

nvim-java should use the same javac version as the currently specified runtime version configured by jdtls. An option to set the sdk used by nvim-java would also fix this issue.

Activity

  1. s1n7ax commented on Jun 9, 2024

    @s1n7ax
    Member

    Try removing.classpath file and cache in ~/.cache/nvim/jdtld

  2. kyerpotts commented on Jun 10, 2024

    @kyerpotts
    Author

    Tried this suggestion, jdtls builds using openjdk-21 when the project loads, however the runner and debugger in nvim-java keep trying to run the build using openjdk-17

  3. s1n7ax commented on Jun 10, 2024

    @s1n7ax
    Member

    @kyerpotts Sounds impossible. We retrieve the java executable information from jdtls meaning, if jdtls uses openjdk-21 for LS, it should be the same for run and debug as well. Has to be some cache issue. But try

    jdk = {
      -- install jdk using mason.nvim
      auto_install = true,
    }

    When setup. This will disable auto installation of jdk 17. Then remove the JDK from mason. Clear the .classpaths, .projects & jdtls cache. Make sure you have not set jdk-17 as the runtime in pom.xml. Try again.

  4. changed the title [-]bug: [/-] [+]bug: jdtls is not using jdk-21[/+] on Jun 10, 2024
  5. s1n7ax commented on Jun 10, 2024

    @s1n7ax
    Member

    @kyerpotts
    Additionally, add this to make sure

        String version = System.getProperty("java.version");
        System.out.println(">>>>>>>>>" + version);
    
    
  6. kyerpotts commented on Jun 11, 2024

    @kyerpotts
    Author

    On further inspection it looks like the problem is only for java classes that are not part of gradle or maven projects.
    I was trying to debug a small program that had no need for a build tool. Is this expected behavior for nvim-java?

  7. Opposite34 commented on Jun 22, 2024

    @Opposite34

    @kyerpotts Sounds impossible. We retrieve the java executable information from jdtls meaning, if jdtls uses openjdk-21 for LS, it should be the same for run and debug as well. Has to be some cache issue. But try

    jdk = {
      -- install jdk using mason.nvim
      auto_install = true,
    }

    When setup. This will disable auto installation of jdk 17. Then remove the JDK from mason. Clear the .classpaths, .projects & jdtls cache. Make sure you have not set jdk-17 as the runtime in pom.xml. Try again.

    I think you meant this?

    jdk = {
      -- install jdk using mason.nvim
      auto_install = false,
    }

    Either way, no matter the setup, mason forces installation of openjdk-17 even after doing MasonUninstall...

    and sure enough if you use jdk-21 it errors because of class version:

    java.lang.UnsupportedClassVersionError: Preview features are not enabled for MyClass (class file 
    version 65.65535). Try running with '--enable-preview'
    

    EDITED: You can kinda solved this by adding home above the config like so:

    ...
    --in jdtls setup of your lspconfig
    java = {
      home = "PATH_TO_RUNTIME",
      configuration = {
      runtimes = {
        {
          name = "JavaSE",
          path = "PATH_TO_RUNTIME",
          default = true,
         },
       },
      }
    }

    In particular, for the op @kyerpotts , since you're using archlinux. I recommend Arch's java-runtime-common package. This allows you to use the command archlinux-java set JDK_VERSION which I believe automatically symlink/set the runtime version to /usr/lib/jvm/default-runtime (which you can just put in the nvim-lspconfig) - allowing from switching version via cmdline instead of dealing with mason and whatnot.

    EDITED2: It seems I have something messed up on my end other than this issue. I'll open a new issue and discuss there. okay it seems like it's something to do with jdtls not loading the packages used properly for the projects I'm using in jdk-21... said projects work in jdk-17... I'll debug this further but I think this is a niche thing so I won't put a new issue.

    On further inspection it looks like the problem is only for java classes that are not part of gradle or maven projects. I was trying to debug a small program that had no need for a build tool. Is this expected behavior for nvim-java?

    If the problem is not a part of a gradle or maven project, then it also doesn't know what to do on my end. With a proper project setup it works fine, however.

  8. s1n7ax commented on Jul 7, 2024

    @s1n7ax
    Member

    @Opposite34 The reason why mason install openjdk even when you have set it to false is because java.setup being called twice. First time with the configuration you have provided and the second time with the default empty table (by default auto_install is true). I have added validations to check if setup is being called twice. I had invalid config instructions for LazyVim so checkout the new config instructions to fix it.

    https://github.com/nvim-java/nvim-java?tab=readme-ov-file#hammer-how-to-install

    @kyerpotts For runtime thing, I assumed it will use the default in the config. Once again, this could be because lspconfig.jdtls.setup() is being called more than once so your configurations are overridden by consequent calls. I have added validations for this as well, but validations might not warn you given the order of how the plugins are being loaded.

    Either way, I'm adding a command to change the JDK. I think I might release it today assuming I can find the time.

  9. s1n7ax commented on Jul 7, 2024

    @s1n7ax
    Member

    Make sure to update lazy.nvim to latest. I'm using a new feature in lazy.nvim to load deps in the latest install instructions

  10. s1n7ax commented on Jul 8, 2024

    @s1n7ax
    Member

    Background Story

    @kyerpotts @Opposite34 I tested this. Plugin actually works as I expected but ~/.cache/nvim/jdtls has be removed upon runtime change because by default it's cached.

    This issue you are facing is actually a limitation in JDTLS. As you can see from the readme, it compiles the source using 19 class version. But when we run, you are using the 21 version and it expect the class version to be 21.

    image

    To confirm the theory, I tried Java 19 to run and it works without any issue,
    image

    image

    Temporary solution

    You can use JavaProfile command to create a new profile to the main with --enable-preview vm flag.

    image

  11. s1n7ax commented on Jul 8, 2024

    @s1n7ax
    Member

    I noticed that profile doesn't apply right away in the same session. That's a bug and obviously, I have to add --enable-preview for jdtls not supported versions. That will be done with this issue.

    #241

  12. linked a pull request that will close this issuefeat: add command to change the runtime #244on Jul 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions