Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java lsp not work #97

Closed
xuliefeng opened this issue Sep 8, 2021 · 14 comments
Closed

java lsp not work #97

xuliefeng opened this issue Sep 8, 2021 · 14 comments

Comments

@xuliefeng
Copy link

hi, I followed the plugin and it works fine in lua but not work for java。Please help me to see if the configuration is wrong

require'lsp_signature'.setup {
bind = true,
floating_window = true,
hint_enable = false,
hint_prefix = "",
extra_trigger_chars = {"(", ","},
hi_parameter = "Search",
float_window_above_cur_line = false,
log_path = vim.fn.expand("$HOME") .. ".cache/nvim/sig.log",
handler_opts = { border = 'single'},
}

I am using vim-cmp at the same time, and it works fine

@ray-x
Copy link
Owner

ray-x commented Sep 8, 2021

I can reproduce the issue. From what I saw, JDTLS does not send any signature help back to neovim. What I got is

{
  bufnr = 1,
  client_id = 1,
  method = "textDocument/signatureHelp"
}

I tried to send lua vim.lsp.buf.signature_help(), Also there is no response .

If it is not issue from jdtls, then there maybe something wrong with neovim lsp framework.

@xuliefeng
Copy link
Author

我可以重现这个问题。 据我所知,JDTLS 不会将任何签名帮助发送回 Neovim。 我得到的是

{ 
   缓冲区 =  1 , 
   客户端 ID =  1 , 
   方法 =  " 文本文档/签名帮助 " 
 } 

我试着发送 lua vim.lsp.buf.signature_help(),也没有回应。

如果不是 jdtls 的问题,那么可能是 neovim lsp 框架有问题。

ok thanks

@ray-x
Copy link
Owner

ray-x commented Sep 8, 2021

I believe jdtls disable signature by default, please check these threads on how to turn it on

eclipse-jdtls/eclipse.jdt.ls#1436

and

mfussenegger/nvim-jdtls#88

@xuliefeng
Copy link
Author

Yes, I have solved it. Now it works normally. thanks

@ray-x
Copy link
Owner

ray-x commented Sep 14, 2021

For document purpose:
JDTLS setup need to include:

local jdtcfg = {
    settings = {
      java = {signatureHelp = {enabled = true}, contentProvider = {preferred = 'fernflower'}}
    },
    on_init = function(client)
      if client.config.settings then
        client.notify('workspace/didChangeConfiguration', {settings = client.config.settings})
      end
    end
  }

require('lspconfig').setup(jdtcfg)

Alsp please make sure the $JDTLS_HOME and $JAVA_HOME is correct.

@gangov
Copy link

gangov commented Oct 17, 2023

can you please how would this look like with the following:

  {
    "ray-x/lsp_signature.nvim",
    config = function()
      require"lsp_signature".setup({
        -- …
      })
    end,
  }

@ray-x
Copy link
Owner

ray-x commented Oct 19, 2023

Is your java lsp up and running? what is the output of LspInfo command?

@gangov
Copy link

gangov commented Oct 19, 2023

this is what it says

 Language client log: /Users/gangov/.local/state/lvim/lsp.log
 Detected filetype:   java
 
 1 client(s) attached to this buffer: 
 
 Client: jdtls (id: 2, bufnr: [32])
 	filetypes:       java
 	autostart:       true
 	root directory:  /Users/gangov/Development/work/allServices/serviceName
 	cmd:             jdtls -configuration /Users/gangov/.cache/jdtls/config -data /Users/gangov/.cache/jdtls/workspace --jvm-arg=-javaagent:/Users/gangov/.local/share/java/lombok.jar
 
 1 active client(s) not attached to this buffer: 
 
 Client: tsserver (id: 1, bufnr: [19])
 	filetypes:       javascript, javascriptreact, javascript.jsx, typescript, typescriptreact, typescript.tsx
 	autostart:       true
 	root directory:  Running in single file mode.
 	cmd:             typescript-language-server --stdio
 
 Configured servers list: jdtls, tsserver, tailwindcss

@ray-x
Copy link
Owner

ray-x commented Oct 19, 2023

I do not use java. But from my earlier comments, it seems jdtls disabled the signature by default. You might need to set up lspconfig like this:

local jdtcfg = {
    settings = {
      java = {signatureHelp = {enabled = true}, contentProvider = {preferred = 'fernflower'}}
    },
    on_init = function(client)
      if client.config.settings then
        client.notify('workspace/didChangeConfiguration', {settings = client.config.settings})
      end
    end
  }

require('lspconfig').setup(jdtcfg)

@gangov
Copy link

gangov commented Oct 19, 2023

so something like this doesn't work:

local jdtcfg = {
  settings = {
    java = {signatureHelp = {enabled = true}, contentProvider = {preferred = 'fernflower'}}
  },
  on_init = function(client)
    if client.config.settings then
      client.notify('workspace/didChangeConfiguration', {settings = client.config.settings})
    end
  end
}

lvim.plugins = {
  {
    "ray-x/lsp_signature.nvim",
    config = function()
      require('lspconfig').setup(jdtcfg)
    end,
  }
}

@ray-x
Copy link
Owner

ray-x commented Oct 20, 2023

I wish I could offer more help but I spent half an hour without even getting jdtls running. I checked the behaviour of vscode and it also failed to get lsp setup and do some simple tasks like auto-complete.
From what I saw you may need something like https://github.com/mfussenegger/nvim-jdtls

@gangov
Copy link

gangov commented Oct 20, 2023

no worries @ray-x I appreciate your help and the work you put into this tool! 🤜🤛

@TheRustifyer
Copy link

TheRustifyer commented Feb 23, 2024

so something like this doesn't work:

local jdtcfg = {
  settings = {
    java = {signatureHelp = {enabled = true}, contentProvider = {preferred = 'fernflower'}}
  },
  on_init = function(client)
    if client.config.settings then
      client.notify('workspace/didChangeConfiguration', {settings = client.config.settings})
    end
  end
}

lvim.plugins = {
  {
    "ray-x/lsp_signature.nvim",
    config = function()
      require('lspconfig').setup(jdtcfg)
    end,
  }
}

For future readers, and for reference, here's how a JDTLS configuration should look like.
Note that JDTLS is a bit special, as any other thing in the Java world.
Best and easy way to configure JDTLS is by having a java.lua file under a folder named ftplugin on your Neovim's config directory (on the root of the config folder)

local jdtls = require('jdtls')

local procs = require('the-rustifyer.utils.procedures')
local globals = require('the-rustifyer.core.globals')
local consts = require('the-rustifyer.core.constants')

local p_sep = globals.path.sep
local mason_path = consts.dirs.nvim_data .. p_sep .. 'mason' .. p_sep .. 'packages'

local jdtls_path = mason_path .. p_sep .. 'jdtls'
local jdtls_jar_path = vim.fn.glob(jdtls_path .. '/plugins/org.eclipse.equinox.launcher_*.jar')
-- local root_dir = require('jdtls.setup').find_root({ '.gitignore', 'code/', '.gitattributtes', 'README.md' })

local on_attach = function(_client, bufnr)
    local bufopts = { noremap = true, silent = true, buffer = bufnr }
    -- Java extensions provided by jdtls
    procs.nnoremap("<C-o>", jdtls.organize_imports, bufopts, "Organize imports")
    procs.nnoremap("<space>ev", jdtls.extract_variable, bufopts, "Extract variable")
    procs.nnoremap("<space>ec", jdtls.extract_constant, bufopts, "Extract constant")
    vim.keymap.set('v', "<space>em", [[<ESC><CMD>lua require('jdtls').extract_method(true)<CR>]],
    { noremap = true, silent = true, buffer = bufnr, desc = "Extract method" })
end

local bundles = {
  -- Path to the Microsoft's Java debug plugin
  vim.fn.glob(mason_path .. p_sep .. 'java-debug-adapter/extension/server/com.microsoft.java.debug.plugin-*.jar', 1),
}
-- Extending the bundles table to add the plugin that allows us to debug Java tests within Neovim
vim.list_extend(bundles, vim.split(vim.fn.glob(mason_path .. p_sep .. "java-test/extension/server/*.jar", 1), "\n"))

local config = {
    flags = {
        debounce_text_changes = 80,
    },
    on_attach = on_attach, -- We pass our on_attach keybindings to the configuration map
    root_dir = vim.fn.getcwd(), -- Set the root directory to our found root_marker
    -- Here you can configure eclipse.jdt.ls specific settings
    -- These are defined by the eclipse.jdt.ls project and will be passed to eclipse when starting.
    -- See https://github.com/eclipse/eclipse.jdt.ls/wiki/Running-the-JAVA-LS-server-from-the-command-line#initialize-request
    -- for a list of options

    -- See: https://github.com/eclipse/eclipse.jdt.ls#running-from-the-command-line
    -- The command that starts the language server

    -- 💀
    -- This is the default if not provided, you can remove it. Or adjust as needed.
    -- One dedicated LSP server & client will be started per unique root_dir

    init_options = {
        bundles = bundles,
    },

    cmd = {
        -- 💀
        'java', -- or '/path/to/java17_or_newer/bin/java'
        -- depends on if `java` is in your $PATH env variable and if it points to the right version.

        '-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',
        '-Xmx1g',
        '--add-modules=ALL-SYSTEM',
        '--add-opens', 'java.base/java.util=ALL-UNNAMED',
        '--add-opens', 'java.base/java.lang=ALL-UNNAMED',
        '-javaagent:' .. jdtls_path .. '/lombok.jar',
        -- 💀
        '-jar', jdtls_jar_path,
        -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                       ^^^^^^^^^^^^^^
        -- Must point to the                                                     Change this to
        -- eclipse.jdt.ls installation                                           the actual version


        -- 💀 I only work with Java on Windows or Linux, no need to check anything else
        '-configuration', jdtls_path .. '/config_' .. (globals.sys.is_windows and 'win' or 'linux'),
        -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ^^^^^^
        -- Must point to the                      Change to one of `linux`, `win` or `mac`
        -- eclipse.jdt.ls installation            Depending on your system.


        -- 💀
        -- See `data directory configuration` section in the README
        '-data',
        -- project_root_dir
        vim.fn.getcwd()
    },

    -- Here you can configure eclipse.jdt.ls specific settings
    -- See https://github.com/eclipse/eclipse.jdt.ls/wiki/Running-the-JAVA-LS-server-from-the-command-line#initialize-request
    -- for a list of options
    settings = {
        java = {
            signatureHelp = { enabled = true },
            contentProvider = { preferred = 'fernflower' },  -- Use fernflower to decompile library code
            -- Specify any completion options
            completion = {
                favoriteStaticMembers = {
                    "org.hamcrest.MatcherAssert.assertThat",
                    "org.hamcrest.Matchers.*",
                    "org.hamcrest.CoreMatchers.*",
                    "org.junit.jupiter.api.Assertions.*",
                    "java.util.Objects.requireNonNull",
                    "java.util.Objects.requireNonNullElse",
                    "org.mockito.Mockito.*"
                },
                filteredTypes = {
                    "com.sun.*",
                    "io.micrometer.shaded.*",
                    "java.awt.*",
                    "jdk.*", "sun.*",
                },
            },
            -- Specify any options for organizing imports
            sources = {
                organizeImports = {
                    starThreshold = 9999;
                    staticStarThreshold = 9999;
                },
            },
            -- How code generation should act
            codeGeneration = {
                toString = {
                    template = "${object.className}{${member.name()}=${member.value}, ${otherMembers}}"
                },
                hashCodeEquals = {
                    useJava7Objects = true,
                },
                useBlocks = true,
            },

        }
    },
}

-- This starts a new client & server,
-- or attaches to an existing client & server depending on the `root_dir`.
require('jdtls').start_or_attach(config)

I set up a lot of variables defined on my configuration for make it more convenient, but the important point is just the "skeleton" of the configuration.

I just use Java only professionaly, and I am able to use it every day without issues in my job, so I really hope that this could help anybody in the same situation

EDIT: I download everything related with Java via Mason, so it's very convinient to quickly automate everything if you have multiple set ups, because it's tedious to download everything manually and have to figure all the paths on your own, and that gets worse if you use different OS (this is just for readers to take in consideration why some path variables looks like in the configuration I shared)

@gangov
Copy link

gangov commented Feb 23, 2024

thanks for sharing @TheRustifyer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants