Skip to content

bsp: always put semanticdb-javac on the server classpath - #613

Merged
oyvindberg merged 3 commits into
masterfrom
shared-daemon-semanticdb
Jul 25, 2026
Merged

bsp: always put semanticdb-javac on the server classpath#613
oyvindberg merged 3 commits into
masterfrom
shared-daemon-semanticdb

Conversation

@oyvindberg

@oyvindberg oyvindberg commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Note: this PR now also contains #614 (merged into this branch): every hardcoded version collected into bleep-model/src/scala/bleep/model/Versions.scala and bumped to newest, plus the junit-platform alignment fixes in the test-runner injection. See #614 for the full description. Verified there: bleep-tests 265/265, bleep-bsp-tests 611/611.


Observed live: two 1.0.0-M10+58 daemons running side by side, classpaths differing by exactly one jar — semanticdb-javac-0.11.2. Only the IDE path (bleep bsp) added it (at whatever version Metals requested at initialize), everyone else passed an empty extra classpath, and since the server classpath feeds the JVM key / socket-dir hash, an IDE session and a CLI/MCP session at the same bleep version each spawned their own daemon: two JVMs, two heaps, no shared compilation state.

Change

  • SetupBleepBsp now resolves com.sourcegraph:semanticdb-javac itself and puts it on the server classpath unconditionally, at a pinned DefaultJavaSemanticdbVersion (now living in model.Versions). The version string is hashed into the JVM key in place of the old jar-filename marker.
  • extraServerClasspath parameter is gone; callers pass javaSemanticdbVersion instead. CLI/MCP/query paths pass the default; bleep bsp passes the IDE-requested version when one arrives at initialize — so an IDE pinning a different version still gets a dedicated daemon, which is a fork with a reason rather than a fork by classpath accident.
  • Resolution is cached like the server classpath itself, keyed by the semanticdb version since that's independent of the bleep version.
  • BspProxy.resolveExtraClasspath (bare coursier.Fetch, ignoring configured repos) deleted; resolution now goes through bleep's own CoursierResolver.

Net effect: all clients of one bleep version converge on one shared daemon.

🤖 Generated with Claude Code

The server classpath is part of the JVM key that names the daemon's
socket dir. Only the IDE path (bleep bsp) added semanticdb-javac — at
whatever version Metals requested — so an IDE session and a CLI/MCP
session at the same bleep version each spawned their own daemon: two
JVMs, two heaps, no shared compilation state. Observed live: two
1.0.0-M10+58 daemons whose classpaths differed by exactly that one jar.

Move the resolution into SetupBleepBsp and make it unconditional at a
pinned DefaultJavaSemanticdbVersion (0.11.2, what current Metals asks
for). All callers pass the default; bleep bsp passes the IDE-requested
version when one arrives at initialize, so a genuinely different
version still gets a dedicated daemon — a fork with a reason, instead
of a fork by classpath accident. The resolved jars are cached next to
the server classpath cache, keyed by the semanticdb version.

Co-Authored-By: Claude Fable 5 <[email protected]>
oyvindberg and others added 2 commits July 25, 2026 01:25
Versions bleep chooses — build defaults, fetched tools, artifacts
injected into user classpaths — were scattered across bleep-model,
bleep-core, bleep-cli and bleep-bsp, and had already drifted: the BSP
server's java-semanticdb fallback (0.10.0) disagreed with the client
default (0.11.2), and ZincBridge's compiler-bridge (1.10.4) lagged the
zinc in bleep.yaml (1.12.0). All literals now live in model.Versions;
every previous site references it. Values unchanged in this commit
except the two drifted ones now converging on the intended value:
java-semanticdb fallback follows the client default, compiler-bridge
is bumped separately.

Co-Authored-By: Claude Fable 5 <[email protected]>
All verified against repo1.maven.org metadata (the search.maven.org
index is stale) and coupled artifacts checked to exist:

  Scala 2.13.18 / 3.8.4, Scala.js 1.22.0, Scala Native 0.5.12,
  Kotlin 2.0.21 / 2.1.21 / 2.3.21, ECJ 3.46.0, ktfmt 0.64,
  scalafmt 3.11.4, Node 24.18.0, semanticdb-scalac 4.17.3,
  semanticdb-javac 0.12.3, compiler-bridge 1.12.0 (now matching the
  zinc in bleep.yaml), junit platform/vintage/jupiter 1.14.4/5.14.4,
  kotest 6.2.3, munit 1.3.4.

Kept: Scala 2.12.21 and google-java-format 1.35.0 (already newest),
ZincScala (must match bleep's own build), test-interface 1.0 and the
two interface shims (no newer release exists).

The junit bumps exposed that the test-runner injection was only ever
safe by luck: bleep appends a separately-resolved launcher/vintage jar
set next to whatever junit-platform the project brings, and modern
junit hard-fails on any version skew between launcher, engine and
commons jars ("OutputDirectoryCreator not available", NoSuchMethodError
in discovery). Fixes:

- The injected junit set is now resolved at the junit-platform version
  detected on the project's own test classpath (engine jar filename),
  falling back to the newest defaults only when the project has no
  junit-platform at all. Cache keyed by (resolver, detected version).
- junit-jupiter-engine is pinned in the injected set so the stale 5.9.1
  that jupiter-interface drags in transitively gets evicted to the
  aligned version.
- The generated kotlin build drops its junit-jupiter dependency: the
  generated test is pure kotest, and jupiter's junit-platform line
  (1.14.x) disagrees with the one kotest ships (1.13.x), making the
  project's own resolution internally unaligned.

Test expectations that pinned literals now reference model.Versions;
snapshots regenerated. bleep-tests 265/265, bleep-bsp-tests 611/611.

Co-Authored-By: Claude Fable 5 <[email protected]>
@oyvindberg
oyvindberg merged commit 8db61d1 into master Jul 25, 2026
9 of 10 checks passed
@oyvindberg
oyvindberg deleted the shared-daemon-semanticdb branch July 25, 2026 00:11
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.

1 participant