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

Completion of third party dependencies #525

Closed mfulz closed 1 year ago

mfulz commented 1 year ago

LSP client configuration

      local mason_registry = require("mason-registry")
      local jdtls_pkg = mason_registry.get_package("jdtls")
      local jdtls_path = jdtls_pkg:get_install_path()
      local jdtls_bin = jdtls_path .. "/bin/jdtls"

      local bundles = {}

      -- if mason_registry.has_package("java-test") and mason_registry.has_package("java-debug-adapter") then
      --   -- jdtls tools configuration for debugging support
      --   local java_test_pkg = mason_registry.get_package("java-test")
      --   local java_test_path = java_test_pkg:get_install_path()
      --
      --   local java_dbg_pkg = mason_registry.get_package("java-debug-adapter")
      --   local java_dbg_path = java_dbg_pkg:get_install_path()
      --
      --   local jar_patterns = {
      --     java_dbg_path .. "/extension/server/com.microsoft.java.debug.plugin-*.jar",
      --     java_test_path .. "/extension/server/*.jar"
      --   }
      --
      --   for _, jar_pattern in ipairs(jar_patterns) do
      --     for _, bundle in ipairs(vim.split(vim.fn.glob(jar_pattern), '\n')) do
      --       table.insert(bundles, bundle)
      --     end
      --   end
      -- end

      local extendedClientCapabilities = vim.tbl_deep_extend("force", require("jdtls").extendedClientCapabilities, {
        resolveAdditionalTextEditsSupport = true,
        progressReportProvider = false,
      });

      local function print_test_results(items)
        if #items > 0 then
          vim.cmd([[Trouble quickfix]])
        else
          vim.cmd([[TroubleClose quickfix]])
        end
      end

      vim.api.nvim_create_autocmd("FileType", {
        pattern = "java",
        callback = function()
          -- Find root of project
          local root_markers = { ".git", "mvnw", "gradlew", "build.gradle" }
          local root_dir = require("jdtls.setup").find_root(root_markers)
          if root_dir == "" then
            return
          end
          -- local workspace_folder = "/tmp/nvim/xprivng"
          local workspace_folder = "/tmp/nvim/jdtls/" .. vim.fn.fnamemodify(root_dir, ":p:h:t")
          -- local workspace_folder = root_dir .. "/../workspaces/" .. vim.fn.fnamemodify(root_dir, ":p:h:t")

          local jdtls = require("jdtls")
          local jdtls_config = vim.tbl_deep_extend("force", opts, {
            on_attach = require("lazyvim.util").on_attach(function(client, buffer)
              -- custom keymaps
              vim.keymap.set("n", "<leader>co", function() require("jdtls").organize_imports() end,
                { buffer = buffer, desc = "Organize Imports" })
              vim.keymap.set("n", "<leader>ct",
                function() require("jdtls").pick_test({ bufnr = buffer, after_test = print_test_results }) end,
                { buffer = buffer, desc = "Run Test" })
              -- require("jdtls").setup_dap({ hotcodereplace = "auto" })
              -- require("jdtls.dap").setup_dap_main_class_configs()
              -- require("jdtls.setup").add_commands()
            end),
            cmd = {
              jdtls_bin,
              "-data", workspace_folder,
              "--jvm-arg=-Xmx1G"
            },
            settings = {
              java = {
                configuration = {
                  runtimes = {
                    {
                      name = "JavaSE-1.7",
                      path = "/usr/lib/jvm/java-7-openjdk",
                    },
                    {
                      name = "JavaSE-1.8",
                      path = "/usr/lib/jvm/java-8-openjdk",
                    },
                    {
                      name = "JavaSE-11",
                      path = "/usr/lib/jvm/java-11-openjdk",
                    },
                    {
                      name = "JavaSE-17",
                      path = "/usr/lib/jvm/java-17-openjdk",
                      default = true,
                    },
                    {
                      name = "JavaSE-20",
                      path = "/usr/lib/jvm/java-20-openjdk",
                    },
                  },
                  updateBuildConfiguration = "automatic",
                },
                codeGeneration = {
                  toString = {
                    template = "${object.className}{${member.name()}=${member.value}, ${otherMembers}}"
                  },
                  useBlocks = true,
                },
                -- completion = {
                --   favoriteStaticMembers = {
                --     "org.assertj.core.api.Assertions.*",
                --     "org.junit.Assert.*",
                --     "org.junit.Assume.*",
                --     "org.junit.jupiter.api.Assertions.*",
                --     "org.junit.jupiter.api.Assumptions.*",
                --     "org.junit.jupiter.api.DynamicContainer.*",
                --     "org.junit.jupiter.api.DynamicTest.*",
                --     "org.mockito.Mockito.*",
                --     "org.mockito.ArgumentMatchers.*",
                --     "org.mockito.Answers.*",
                --   },
                --   importOrder = {
                --     "#",
                --     "java",
                --     "javax",
                --     "org",
                --     "com"
                --   },
                -- },
                contentProvider = { preferred = "fernflower" },
                eclipse = {
                  downloadSources = true,
                },
                flags = {
                  allow_incremental_sync = true,
                  server_side_fuzzy_completion = true
                },
                implementationsCodeLens = {
                  enabled = false, --Don"t automatically show implementations
                },
                inlayHints = {
                  parameterNames = { enabled = "literals" }
                },
                maven = {
                  downloadSources = true,
                },
                referencesCodeLens = {
                  enabled = false, --Don"t automatically show references
                },
                references = {
                  includeDecompiledSources = true,
                },
                saveActions = {
                  organizeImports = true,
                },
                signatureHelp = { enabled = true },
                sources = {
                  organizeImports = {
                    starThreshold = 9999,
                    staticStarThreshold = 9999,
                  },
                },
              },
            },
            init_options = {
              extendedClientCapabilities = extendedClientCapabilities,
              bundles = bundles,
            }
          })
          jdtls.start_or_attach(jdtls_config)
        end,
      })
      return true
    end,
  },
},

Eclipse.jdt.ls version

1.25.0

Steps to Reproduce

I've tried nearly every configuration of nvim-jdtls now for days:

I'm unable to get completions for dependencies added via gradle. I've created a minimal project that could be used for testing: https://github.com/mfulz/XPosedTest

I was able to pin down the problem (at least as far as I could understand - I'm a gradle / java noob) that I looks like the .classpath file is always the same and jdtls is not adding any deps to it: `<?xml version="1.0" encoding="UTF-8"?>

` When I'm adding some classpathentry to the file manually and setting it read only (to avoid jdtls overwriting it) it is able to autocomplete the deps from there. I'm not sure if this is an issue with jdtls, nvim-jdtls or my gradle config itself (but as the project builds fine and is runnable I doubt it is an issue with the project itself) Further using this project in android-studio the completion, etc. works ### Expected Result jdtls should find the dependencies defined in gradle files ### Actual Result JdtShowLogs: !SESSION 2023-07-05 23:26:49.914 ----------------------------------------------- eclipse.buildId=unknown java.version=17.0.7 java.vendor=N/A BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=en_US Command-line arguments: -data /tmp/nvim/jdtls/app !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:50.849 !MESSAGE class org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin is started !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.031 !MESSAGE Main thread is waiting !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.071 !MESSAGE >> initialize !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.072 !MESSAGE Initializing Java Language Server 1.25.0.202306291518 !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.097 !MESSAGE Static Commands: [] !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.097 !MESSAGE Non-Static Commands: [java.edit.organizeImports, java.project.refreshDiagnostics, java.project.import, java.navigate.openTypeHierarchy, java.project.removeFromSourcePath, java.project.listSourcePaths, java.project.resolveStackTraceLocation, java.project.getAll, java.reloadBundles, java.project.isTestFile, java.edit.handlePasteEvent, java.project.getClasspaths, java.navigate.resolveTypeHierarchy, java.edit.stringFormatting, java.project.getSettings, java.project.updateSourceAttachment, java.project.resolveWorkspaceSymbol, java.project.upgradeGradle, java.decompile, java.project.createModuleInfo, java.protobuf.generateSources, java.project.resolveSourceAttachment, java.project.addToSourcePath, java.completion.onDidSelect] !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.097 !MESSAGE Static Commands: [] !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.097 !MESSAGE Non-Static Commands: [vscode.java.checkProjectSettings, vscode.java.isOnClasspath, vscode.java.fetchUsageData, vscode.java.validateLaunchConfig, vscode.java.resolveInlineVariables, vscode.java.resolveClassFilters, vscode.java.resolveMainMethod, vscode.java.resolveClasspath, vscode.java.resolveBuildFiles, vscode.java.resolveMainClass, vscode.java.updateDebugSettings, vscode.java.resolveSourceUri, vscode.java.fetchPlatformSettings, vscode.java.buildWorkspace, vscode.java.startDebugSession, vscode.java.inferLaunchCommandLength, vscode.java.resolveElementAtSelection, vscode.java.resolveJavaExecutable] !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.098 !MESSAGE Static Commands: [] !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.098 !MESSAGE Non-Static Commands: [vscode.java.test.findJavaProjects, vscode.java.test.findTestPackagesAndTypes, vscode.java.test.findTestTypesAndMethods, vscode.java.test.resolvePath, vscode.java.test.findTestLocation, vscode.java.test.get.testpath, vscode.java.test.findDirectTestChildrenForClass, vscode.java.test.navigateToTestOrTarget, vscode.java.test.junit.argument, vscode.java.test.generateTests] !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.103 !MESSAGE Started org.eclipse.m2e.core 1ms !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.778 !MESSAGE ProjectRegistryRefreshJob finished 675ms !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.793 !MESSAGE Started org.eclipse.buildship.core 15ms !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.802 !MESSAGE RepositoryRegistryUpdateJob finished 0ms !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.805 !MESSAGE >> initialized !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.809 !MESSAGE Creating the Java project jdt.ls-java-project !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:51.852 !MESSAGE Finished creating the Java project jdt.ls-java-project !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:52.210 !MESSAGE Importing Gradle project(s) !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:26:52.211 !MESSAGE No previous Gradle project at /home/mfulz/AndroidStudioProjects/XPosedTest, it must be synchronized !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.320 !MESSAGE Workspace initialized in 28519ms !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.339 !MESSAGE >> initialization job finished !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.342 !MESSAGE >> registerWatchers' !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.357 !MESSAGE Setting /usr/lib/jvm/java-8-openjdk as 'JavaSE-1.8' environment (id:/usr/lib/jvm/java-8-openjdk) !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.358 !MESSAGE Setting /usr/lib/jvm/java-7-openjdk as 'JavaSE-1.7' environment (id:/usr/lib/jvm/java-7-openjdk) !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.361 !MESSAGE Setting /usr/lib/jvm/java-20-openjdk as 'JavaSE-20' environment (id:/usr/lib/jvm/java-20-openjdk) !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.363 !MESSAGE Setting /usr/lib/jvm/java-11-openjdk as 'JavaSE-11' environment (id:/usr/lib/jvm/java-11-openjdk) !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.365 !MESSAGE Setting /usr/lib/jvm/java-17-openjdk as 'JavaSE-17' environment (id:1688592410905) !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.402 !MESSAGE JVM Runtimes changed, saving new configuration !ENTRY org.eclipse.jdt.ls.core 4 0 2023-07-05 23:27:20.459 !MESSAGE Command _java.reloadBundles.command not supported on client !ENTRY org.eclipse.jdt.ls.core 4 0 2023-07-05 23:27:20.638 !MESSAGE Error occured while building workspace. Details: message: The import de.robv cannot be resolved; code: 268435846; resource: /home/mfulz/AndroidStudioProjects/XPosedTest/app/src/main/java/de/olznet/Tutorial.java; line: 5 message: IXposedHookLoadPackage cannot be resolved to a type; code: 16777218; resource: /home/mfulz/AndroidStudioProjects/XPosedTest/app/src/main/java/de/olznet/Tutorial.java; line: 7 message: LoadPackageParam cannot be resolved to a type; code: 16777218; resource: /home/mfulz/AndroidStudioProjects/XPosedTest/app/src/main/java/de/olznet/Tutorial.java; line: 8 message: XposedBridge cannot be resolved; code: 570425394; resource: /home/mfulz/AndroidStudioProjects/XPosedTest/app/src/main/java/de/olznet/Tutorial.java; line: 9 message: The import de.robv cannot be resolved; code: 268435846; resource: /home/mfulz/AndroidStudioProjects/XPosedTest/app/src/main/java/de/olznet/Tutorial.java; line: 3 message: The import de.robv cannot be resolved; code: 268435846; resource: /home/mfulz/AndroidStudioProjects/XPosedTest/app/src/main/java/de/olznet/Tutorial.java; line: 4 !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:20.677 !MESSAGE >> build jobs finished !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:21.064 !MESSAGE Reconciled 1. Took 1 ms !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:21.691 !MESSAGE begin problem for /Tutorial.java !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:21.691 !MESSAGE 6 problems reported for /Tutorial.java !ENTRY org.eclipse.jdt.ls.core 1 0 2023-07-05 23:27:21.693 !MESSAGE Validated 1. Took 27 ms
mfulz commented 1 year ago

Further info: A.e: Adding this to the app/.classpath file: <classpathentry kind="lib" path="/home/mfulz/.gradle/caches/modules-2/files-2.1/de.robv.android.xposed/api/82/35866b507b360d4789ff389ad7386b6e8bbf6cc4/api-82.jar"/> The completions are working fine

mfussenegger commented 1 year ago

I get the same errors:

app/src/main/java/de/olznet/Tutorial.java|3 col 8-15 error| The import de.robv cannot be resolved
app/src/main/java/de/olznet/Tutorial.java|4 col 8-15 error| The import de.robv cannot be resolved
app/src/main/java/de/olznet/Tutorial.java|5 col 8-15 error| The import de.robv cannot be resolved
app/src/main/java/de/olznet/Tutorial.java|7 col 34-56 error| IXposedHookLoadPackage cannot be resolved to a type
app/src/main/java/de/olznet/Tutorial.java|8 col 39-55 error| LoadPackageParam cannot be resolved to a type
app/src/main/java/de/olznet/Tutorial.java|9 col 5-17 error| XposedBridge cannot be resolved

Looks like a server/eclipse.jdt.ls issue to me. You'll have to create an issue upstream.

Note that android support is declared experimental:

Gradle project support (with experimental Android project import support)

lifei commented 4 months ago

you should enable the androidSupport in configuration.