diff options
| author | Stephen Collings <[email protected]> | 2026-03-09 16:04:08 +0000 |
|---|---|---|
| committer | opencode <[email protected]> | 2026-03-09 16:09:43 +0000 |
| commit | 8b9710e56c041cae4bdc0b865dc4d13bc04edebf (patch) | |
| tree | b3c8c02f30d16f0c01ada859276124a335494197 | |
| parent | c6262f9d4002d86a1f1795c306aa329d45361d12 (diff) | |
| download | opencode-8b9710e56c041cae4bdc0b865dc4d13bc04edebf.tar.gz opencode-8b9710e56c041cae4bdc0b865dc4d13bc04edebf.zip | |
fix: Multiple jdtls LSPs eating memory in java monorepos (#12123)
| -rw-r--r-- | packages/opencode/src/lsp/server.ts | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/packages/opencode/src/lsp/server.ts b/packages/opencode/src/lsp/server.ts index e09fbc97f..405c67285 100644 --- a/packages/opencode/src/lsp/server.ts +++ b/packages/opencode/src/lsp/server.ts @@ -1130,7 +1130,30 @@ export namespace LSPServer { export const JDTLS: Info = { id: "jdtls", - root: NearestRoot(["pom.xml", "build.gradle", "build.gradle.kts", ".project", ".classpath"]), + root: async (file) => { + // Without exclusions, NearestRoot defaults to instance directory so we can't + // distinguish between a) no project found and b) project found at instance dir. + // So we can't choose the root from (potential) monorepo markers first. + // Look for potential subproject markers first while excluding potential monorepo markers. + const settingsMarkers = ["settings.gradle", "settings.gradle.kts"] + const gradleMarkers = ["gradlew", "gradlew.bat"] + const exclusionsForMonorepos = gradleMarkers.concat(settingsMarkers) + + const [projectRoot, wrapperRoot, settingsRoot] = await Promise.all([ + NearestRoot( + ["pom.xml", "build.gradle", "build.gradle.kts", ".project", ".classpath"], + exclusionsForMonorepos, + )(file), + NearestRoot(gradleMarkers, settingsMarkers)(file), + NearestRoot(settingsMarkers)(file), + ]) + + // If projectRoot is undefined we know we are in a monorepo or no project at all. + // So can safely fall through to the other roots + if (projectRoot) return projectRoot + if (wrapperRoot) return wrapperRoot + if (settingsRoot) return settingsRoot + }, extensions: [".java"], async spawn(root) { const java = which("java") |
