mfussenegger / nvim-jdtls

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

Lombok generated methods not being recognised #554

Closed idelice closed 1 year ago

idelice commented 1 year ago

LSP client configuration

return {
  "mfussenegger/nvim-jdtls",
  config = function()
    local home = os.getenv("HOME")
    local jdtls = require("jdtls")

    -- File types that signify a Java project's root directory. This will be
    -- used by eclipse to determine what constitutes a workspace
    local root_markers = { "gradlew", "mvnw", ".git" }
    local root_dir = require("jdtls.setup").find_root(root_markers)

    -- eclipse.jdt.ls stores project specific data within a folder. If you are working
    -- with multiple different projects, each project must use a dedicated data directory.
    -- This variable is used to configure eclipse to use the directory name of the
    -- current project found using the root_marker as the folder for project specific data.
    local workspace_folder = home .. "/.local/share/eclipse/" .. vim.fn.fnamemodify(root_dir, ":p:h:t")

    -- Helper function for creating keymaps
    function nnoremap(rhs, lhs, bufopts, desc)
      bufopts.desc = desc
      vim.keymap.set("n", rhs, lhs, bufopts)
    end

    -- The on_attach function is used to set key maps after the language server
    -- attaches to the current buffer
    local on_attach = function(client, bufnr)
      -- Regular Neovim LSP client keymappings
      local bufopts = { noremap = true, silent = true, buffer = bufnr }
      nnoremap("gD", vim.lsp.buf.declaration, bufopts, "Go to declaration")
      nnoremap("gd", vim.lsp.buf.definition, bufopts, "Go to definition")
      nnoremap("gi", vim.lsp.buf.implementation, bufopts, "Go to implementation")
      nnoremap("K", vim.lsp.buf.hover, bufopts, "Hover text")
      nnoremap("<C-k>", vim.lsp.buf.signature_help, bufopts, "Show signature")
      nnoremap("<space>wa", vim.lsp.buf.add_workspace_folder, bufopts, "Add workspace folder")
      nnoremap("<space>wr", vim.lsp.buf.remove_workspace_folder, bufopts, "Remove workspace folder")
      nnoremap("<space>wl", function()
        print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
      end, bufopts, "List workspace folders")
      nnoremap("<space>D", vim.lsp.buf.type_definition, bufopts, "Go to type definition")
      nnoremap("<space>rn", vim.lsp.buf.rename, bufopts, "Rename")
      nnoremap("<space>ca", vim.lsp.buf.code_action, bufopts, "Code actions")
      vim.keymap.set(
        "v",
        "<space>ca",
        "<ESC><CMD>lua vim.lsp.buf.range_code_action()<CR>",
        { noremap = true, silent = true, buffer = bufnr, desc = "Code actions" }
      )
      nnoremap("<space>f", function()
        vim.lsp.buf.format({ async = true })
      end, bufopts, "Format file")

      -- Java extensions provided by jdtls
      nnoremap("<C-o>", jdtls.organize_imports, bufopts, "Organize imports")
      nnoremap("<space>ev", jdtls.extract_variable, bufopts, "Extract variable")
      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 config = {
      flags = {
        debounce_text_changes = 80,
      },
      on_attach = on_attach, -- We pass our on_attach keybindings to the configuration map
      root_dir = root_dir, -- 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
      settings = {
        java = {
          format = {
            settings = {
              -- Use Google Java style guidelines for formatting
              -- To use, make sure to download the file from https://github.com/google/styleguide/blob/gh-pages/eclipse-java-google-style.xml
              -- and place it in the ~/.local/share/eclipse directory
              url = "/.local/share/eclipse/eclipse-java-google-style.xml",
              profile = "GoogleStyle",
            },
          },
          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,
          },
          -- If you are developing in projects with different Java versions, you need
          -- to tell eclipse.jdt.ls to use the location of the JDK for your Java version
          -- See https://github.com/eclipse/eclipse.jdt.ls/wiki/Running-the-JAVA-LS-server-from-the-command-line#initialize-request
          -- And search for `interface RuntimeOption`
          -- The `name` is NOT arbitrary, but must match one of the elements from `enum ExecutionEnvironment` in the link above
          configuration = {
            runtimes = {
              {
                name = "JavaJDK-18",
                path = home .. "/.sdkman/candidates/java/current",
              },
            },
          },
        },
      },
      -- cmd is the command that starts the language server. Whatever is placed
      -- here is what is passed to the command line to execute jdtls.
      -- Note that eclipse.jdt.ls must be started with a Java version of 17 or higher
      -- See: https://github.com/eclipse/eclipse.jdt.ls#running-from-the-command-line
      -- for the full list of options
      cmd = {
        home .. "/.asdf/installs/java/corretto-17.0.4.9.1/bin/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",
        "-Xmx4g",
        "--add-modules=ALL-SYSTEM",
        "--add-opens",
        "java.base/java.util=ALL-UNNAMED",
        "--add-opens",
        "java.base/java.lang=ALL-UNNAMED",
        -- If you use lombok, download the lombok jar and place it in ~/.local/share/eclipse
        "-javaagent:"
          .. home
          .. "/.local/share/eclipse/lombok.jar",

        -- The jar file is located where jdtls was installed. This will need to be updated
        -- to the location where you installed jdtls
        "-jar",
        vim.fn.glob("/opt/homebrew/Cellar/jdtls/1.18.0/libexec/plugins/org.eclipse.equinox.launcher_*.jar"),

        -- The configuration for jdtls is also placed where jdtls was installed. This will
        -- need to be updated depending on your environment
        "-configuration",
        "/opt/homebrew/Cellar/jdtls/1.18.0/libexec/config_mac",

        -- Use the workspace_folder defined above to store data for this project
        "-data",
        workspace_folder,
      },
    }

    -- Finally, start jdtls. This will run the language server using the configuration we specified,
    -- setup the keymappings, and attach the LSP client to the current buffer
    jdtls.start_or_attach(config)
  end,
}

Eclipse.jdt.ls version

recent

Steps to Reproduce

In a project using gradle, i'm not getting autocomplete for lombok generated getters/setters etc. and at the same time getting errors because it can't find the getter/setter the lombok is generating for my class.

Expected Result

I expect to see and use all generated methods for my POJO that is annotated with lombok annotations like @Getter, @Setter etc.

Actual Result

I get the same type of error for all POJO's that is calling a get/set for it's method:

The method getValue() is undefined for the type MyPojo

idelice commented 1 year ago

Fixed by adding this arg to cmd:

              "--jvm-arg=" .. string.format(
                "-javaagent:%s",
                vim.fn.expand("$HOME/.local/share/nvim/mason/packages/jdtls/lombok.jar")
stefumies commented 3 days ago

I was hoping after searching for this error for days now this would be it, sadly it isnt, I am just about to give up and move to another IDE away from neovim (reluctantly). There seems to be no solution for this lombok issue, despite being raised many years ago also. "Unrecognized option: --jvm-arg=-javaagent:

and even if I alter the javaagent to the suggested call "Error opening zip file or JAR manifest missing

All permissions are correct, jar is fine, Java on classpath 21, /(tried with 17, and 19 also), also tried with downloaded version of jdtls and lombok rather than mason, still same issue, so almost ready to call it a day.

Andras-Csanyi commented 3 days ago

If I remember correctly the config below provided me the methods lombok creates. However, earlier this year lombok had an issue made it not working well with jdtls and it took months to get it fixed. I am saying this just manage expectations.

https://github.com/LunarVim/starter.lvim/pull/84