Skip to content

refactor(java-lsp): one shared default classpath for all Java projects - #6633

Merged
delchev merged 1 commit into
masterfrom
feature/jdtls-default-classpath
Aug 9, 2026
Merged

refactor(java-lsp): one shared default classpath for all Java projects#6633
delchev merged 1 commit into
masterfrom
feature/jdtls-default-classpath

Conversation

@delchev

@delchev delchev commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

What

Every Java project's generated .classpath was byte-identical — nothing in it is project-specific
(src="", the JRE container, the full platform lib set, the compiled-output dir, bin output) — yet it
was re-rendered per project on every LSP connect.

This consolidates it into a single documented, memoised default classpath shared by every Java
project in the workspace, composed of exactly what client Java needs to resolve:

  • the Java standard library (JRE_CONTAINER);
  • the Dirigible SDK + platform jars, one lib entry per ClassPathIndex entry — the full set, because
    generated controllers and BPMN handlers pull in Spring and Flowable, and an SDK-only subset would not
    compile real projects;
  • the registry / published projects, via the flat compiled-output dir
    (<repoRoot>/dirigible/java-compiled/bin) that every client .java on the platform compiles into, so
    one entry resolves both cross-project and published types;
  • plus the project's own sources (src="").

Behaviour is unchanged — the emitted XML is identical. It is now rendered once and reused
(ClassPathIndex.classPathEntries() is cached for the app lifetime and the compiled-output path is
fixed). buildClasspathXml() is renamed to defaultClasspathXml().

One file, +50/-14.

Provenance and staleness — please read before merging

Full disclosure: this commit was authored 2026-06-18 and sat unpushed on a local branch until now; I
found it while cleaning up stale worktrees and branches. I did not write it and have not exercised it
beyond the checks below, so it wants a real review rather than a rubber stamp.

What I did verify:

  • It merges cleanly into current master (git merge-tree reports no conflict), and the PR contains
    exactly this one commit against the current merge base.
  • The refactor is not already in master — master has no defaultClasspathXml and no memoised shared
    classpath.
  • JdtLsManager has however moved on substantially since the commit was written (roughly 115
    insertions / 68 deletions elsewhere in the file): master now fingerprints the classpath, reuses a
    cached JDT.LS index across restarts, and pre-warms the compile classpath at startup. A clean textual
    merge is not proof those interact correctly — in particular whether the new memoisation should
    participate in the existing classpathFingerprint() invalidation, so a changed platform classpath does
    not leave a stale cached .classpath behind. That is the thing to look at closest.
  • The commit message says it is "best paired with the JDT.LS symlink fix (separate PR)", which makes the
    .classpath generate for git-backed projects in the first place. That companion appears to have landed
    already — most likely fix(java-lsp): resolve symlinked git-clone project paths to virtual URIs #6148 (fix(java-lsp): resolve symlinked git-clone project paths to virtual URIs), with Fix Java LSP completion for git-backed projects (follow symlinks) #6038 earlier — so the prerequisite is in place.

No local test run: this touches the JDT.LS launch path, which has no automated coverage in the repo, so
CI plus a manual "open a Java project, check completion resolves platform and cross-project types" is the
real verification.

🤖 Generated with Claude Code

Every project's generated .classpath was byte-identical (nothing in it is
project-specific: src="", the JRE container, the full platform lib set, the
compiled-output dir, output bin), yet it was re-rendered per project on every
LSP connect.

Consolidate it into a single, documented, memoised "default classpath" that
every Java project in the workspace shares, composed of exactly what client
Java needs to resolve:
  - Java standard library (JRE_CONTAINER);
  - the Dirigible SDK + platform jars (one lib entry per ClassPathIndex
    entry - the full set, since generated controllers/BPMN handlers pull in
    Spring/Flowable and an SDK-only subset would not compile real projects);
  - the registry / published projects, via the flat compiled-output dir
    (<repoRoot>/dirigible/java-compiled/bin), into which every client .java
    on the platform compiles - so one entry resolves cross-project and
    published types;
  plus the project's own sources (src="").

Behaviour is unchanged (identical XML); it is now rendered once and reused
(ClassPathIndex.classPathEntries() is cached for the app lifetime and the
compiled-output path is fixed). Renames buildClasspathXml() ->
defaultClasspathXml().

Best paired with the JDT.LS symlink fix (separate PR): that makes the
.classpath generate for git-backed projects in the first place; this defines
what goes in it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* <li><b>the Dirigible SDK + platform jars</b> - one {@code lib} entry per {@link ClassPathIndex}
* entry. This is the full platform jar set: it contains {@code org.eclipse.dirigible.sdk.*} as well
* as the Spring / Flowable / etc. jars that generated controllers and BPMN handlers depend on (an
* SDK-only subset does not compile real projects);</li>
* <li><b>the registry / published projects</b> - one {@code lib} entry for the flat compiled-output
* directory ({@code <repoRoot>/dirigible/java-compiled/bin}). Every client {@code .java} on the
* platform (registry-published and sibling workspace projects) compiles into that one tree, so this
* single entry resolves cross-project and published types.</li>
@delchev
delchev merged commit 2a9151e into master Aug 9, 2026
10 checks passed
@delchev
delchev deleted the feature/jdtls-default-classpath branch August 9, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants