summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorStephen Collings <[email protected]>2026-03-09 16:04:08 +0000
committeropencode <[email protected]>2026-03-09 16:09:43 +0000
commit8b9710e56c041cae4bdc0b865dc4d13bc04edebf (patch)
treeb3c8c02f30d16f0c01ada859276124a335494197 /packages
parentc6262f9d4002d86a1f1795c306aa329d45361d12 (diff)
downloadopencode-8b9710e56c041cae4bdc0b865dc4d13bc04edebf.tar.gz
opencode-8b9710e56c041cae4bdc0b865dc4d13bc04edebf.zip
fix: Multiple jdtls LSPs eating memory in java monorepos (#12123)
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/lsp/server.ts25
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")