Skip to content

java lsp not work #97

Description

@xuliefeng

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

Activity

  1. ray-x commented on Sep 8, 2021

    @ray-x
    Owner

    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.

  2. xuliefeng commented on Sep 8, 2021

    @xuliefeng
    Author

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

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

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

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

    ok thanks

  3. ray-x commented on Sep 8, 2021

    @ray-x
    Owner

    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

  4. xuliefeng commented on Sep 8, 2021

    @xuliefeng
    Author

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

  5. ray-x commented on Sep 14, 2021

    @ray-x
    Owner

    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.

  6. gangov commented on Oct 17, 2023

    @gangov

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

      {
        "ray-x/lsp_signature.nvim",
        config = function()
          require"lsp_signature".setup({
            -- …
          })
        end,
      }
    
  7. ray-x commented on Oct 19, 2023

    @ray-x
    Owner

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

  8. gangov commented on Oct 19, 2023

    @gangov

    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
    
  9. ray-x commented on Oct 19, 2023

    @ray-x
    Owner

    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)
  10. gangov commented on Oct 19, 2023

    @gangov

    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,
      }
    }
    
  11. ray-x commented on Oct 20, 2023

    @ray-x
    Owner

    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

  12. gangov commented on Oct 20, 2023

    @gangov

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

  13. TheRustifyer commented on Feb 23, 2024

    @TheRustifyer

    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)

  14. gangov commented on Feb 23, 2024

    @gangov

    thanks for sharing @TheRustifyer

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions