mfussenegger / nvim-jdtls

Extensions for the built-in LSP support in Neovim for eclipse.jdt.ls
GNU General Public License v3.0
979 stars 62 forks source link

Goto definition of library class results in error #639

Closed WizardStark closed 3 months ago

WizardStark commented 3 months ago

LSP client configuration

    opts = {
        root_markers = { ".git", "mvnw", "gradlew", "pom.xml", "build.gradle" },
    },
    config = function(_, opts)
        local resolve_opts = function()
            local root_dir = require("jdtls.setup").find_root(opts.root_markers)
            local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":p:h:t")
            local workspace_dir = vim.fn.stdpath("cache") .. "/jdtls/workspace-root/" .. project_name
            if vim.loop.fs_stat(workspace_dir) == nil then
                os.execute("mkdir " .. workspace_dir)
            end
            local install_path = require("mason-registry").get_package("jdtls"):get_install_path()
            local os
            if vim.fn.has("macunix") then
                os = "mac"
            else
                os = "linux"
            end

            return {
                cmd = {
                    "java",
                    "-Declipse.application=org.eclipse.jdt.ls.core.id1",
                    "-Dosgi.bundles.defaultStartLevel=4",
                    "-Declipse.product=org.eclipse.jdt.ls.core.product",
                    "-Dlog.protocol=true",
                    "-Dlog.level=ALL",
                    "-javaagent:" .. install_path .. "/lombok.jar",
                    "-Xmx1g",
                    "--add-modules=ALL-SYSTEM",
                    "--add-opens",
                    "java.base/java.util=ALL-UNNAMED",
                    "--add-opens",
                    "java.base/java.lang=ALL-UNNAMED",
                    "-jar",
                    vim.fn.glob(install_path .. "/plugins/org.eclipse.equinox.launcher_*.jar"),
                    "-configuration",
                    install_path .. "/config_" .. os,
                    "-data",
                    workspace_dir,
                },
                root_dir = root_dir,
            }
        end

Eclipse.jdt.ls version

1.31.0

Steps to Reproduce

In a maven project (in this case, https://github.com/OpenAPITools/openapi-generator), call vim.lsp.buf.definition on a library class (either a class in a maven dependency or the Java standard library).

In this case the standard java.util.Arrays class.

Expected Result

Open relevant class file

Actual Result

I get the following error:

Error executing vim.schedule lua callback: BufReadCmd Autocommands for "jdt://*": Vim(lua):E5108: Error executing lua /home/user/.local/share/nvim/lazy/nvim-jdtls/lua/jdtls.lua:1134: Must have a `jdtls` client to load class file or jdt uri
stack traceback:
    [C]: in function 'assert'
    /home/user/.local/share/nvim/lazy/nvim-jdtls/lua/jdtls.lua:1134: in function 'open_classfile'
    [string ":lua"]:1: in main chunk
    [C]: in function 'bufload'
    /usr/local/share/nvim/runtime/lua/vim/lsp/util.lua:272: in function 'get_lines'
    /usr/local/share/nvim/runtime/lua/vim/lsp/util.lua:1822: in function 'locations_to_items'
    /usr/local/share/nvim/runtime/lua/vim/lsp/handlers.lua:398: in function 'handler'
    /usr/local/share/nvim/runtime/lua/vim/lsp.lua:1393: in function ''
    vim/_editor.lua: in function <vim/_editor.lua:0>
stack traceback:
    [C]: in function 'bufload'
    /usr/local/share/nvim/runtime/lua/vim/lsp/util.lua:272: in function 'get_lines'
    /usr/local/share/nvim/runtime/lua/vim/lsp/util.lua:1822: in function 'locations_to_items'
    /usr/local/share/nvim/runtime/lua/vim/lsp/handlers.lua:398: in function 'handler'
    /usr/local/share/nvim/runtime/lua/vim/lsp.lua:1393: in function ''
    vim/_editor.lua: in function <vim/_editor.lua:0>

This seems to be very similar to #59, so I performed the steps in that issue,

The autocmd appears to be registered correctly:

--- Autocommands ---
BufReadCmd
jdt://*lua require('jdtls').open_classfile(vim.fn.expand('<amatch>'))
    Last set from ~/.local/share/nvim/lazy/nvim-jdtls/plugin/nvim_jdtls.vim line 6

When manually calling require('jdtls').open_classfile("jdt://contents/java.base...api%5C/=/=/maven.pomderived=/true=/%3Cjava.util(Arrays.class") the current buffer content is replaced with the appropriate Array class content.

From some further debugging I identified that the bufnr set here is different than that when calling vim.api.nvim_get_current_buf in the current buffer, resulting in client being nil as no lsp is attached to this other bufnr.

All other functionality of jdtls appears to work (go to definition of classes in the project, signature help, rename etc.).

Any help in this regard would be greatly appreciated

mfussenegger commented 3 months ago

Can this be reproduced without lazy?

WizardStark commented 3 months ago

I moved the config around to ftplugin/java.lua as per the README and it worked as expected. This was strange to me as ftplugin just uses a ft autocmd under the hood. Turns out the autocmd that I used to trigger start_or_attach() was at fault, this check broke it.

vim.api.nvim_create_autocmd("Filetype", {
                pattern = "java",
                callback = function()
                    local start_opts = resolve_opts()
            ->      if start_opts.root_dir and start_opts.root_dir ~= "" then
                        require("jdtls").start_or_attach(start_opts)
                    end
                end,
            })

After removing that it functioned as expected. Sorry for the unnecessary issue!