Releases: aviadshiber/java-functional-lsp
v0.9.1
What's new
- Inside-out workspace expansion: Cross-module go-to-definition now works. After jdtls initializes on the first file, the workspace is immediately expanded to the full project root before any file notifications are flushed — so jdtls discovers all sibling modules and serves cross-module navigation from the first request.
- Fixed spurious error logs:
_analyze_and_publishno longer logsERROR: Error re-publishing diagnosticsfor decompiled virtual sources in the jdtls cache (jdt.ls-java-project). These are now silently skipped. - Queue saturation warning: The 200-notification queue now logs a warning when it fills up so missed
didOpenevents are diagnosable.
v0.9.0
What's new
- Merkle-tree module snapshot for incremental file-change detection between sessions
- On plugin restart after
git pull, changed Java files are forwarded to jdtls viaworkspace/didChangeWatchedFiles, triggering an incremental rebuild instead of a full cold-start re-index - Tracks
*.java+pom.xml/build.gradle/build.gradle.ktsper module - BLAKE2b content hashing with 64 KiB streaming reads; root hash is stable and O(1) comparable
- Snapshots stored in
~/.cache/jdtls-snapshots/(outside data-dir, survives version-bump wipes) - Safety bounds: modules >20 000 files are skipped; snapshot files >100 000 entries rejected
- First-READY-only guard: diff notification fires exactly once per module per session
- Correct LSP FileChangeType split: added→Created, modified→Changed, removed→Deleted
- On plugin restart after
v0.8.1
Fix: Auto-detect JetBrains IDEs and skip jdtls proxy
IntelliJ with LSP4IJ stopped rendering java-functional-lsp diagnostics after v0.8.0 added jdtls proxy support. The dynamic capability registration conflicts with IntelliJ's native Java support.
Changes
- Auto-detect JetBrains IDEs from
clientInfo.nameand skip jdtls proxy (IntelliJ provides native Java support) - Custom tree-sitter diagnostics + code actions continue normally
- Env var override:
JAVA_FUNCTIONAL_LSP_JDTLS=off/on/no-register no-registerdebug mode to isolate dynamic registration as root cause- Generation counter prevents stale capability registrations on re-init
- Regex pattern length cap (500 chars) to mitigate ReDoS
- 8 new tests for detection, overrides, and diagnostics
Upgrade
brew upgrade java-functional-lsp
# or
pip install --upgrade java-functional-lspAfter upgrading, restart IntelliJ — diagnostics should appear automatically. Server logs will show: JetBrains IDE detected (...) — skipping jdtls proxy.
v0.8.0
What's Changed
Fix: jdtls stale cache + isolation from custom diagnostics
Root cause fix: jdtls cached indexes built before the Lombok agent was added caused AssertionFailedException and silently broke @Value(staticConstructor = "of") processing. The server now clears the jdtls cache on version upgrade via a .version marker file — no stale state survives a brew upgrade.
jdtls isolation: jdtls failures no longer suppress custom diagnostics (hints + code actions). All jdtls processing is wrapped in try/except, and all handler paths have error isolation.
Changes
- Clear jdtls data cache on server version change (
.versionmarker) - All blocking startup I/O (cache clearing, Lombok discovery, env build) runs in
run_in_executor - Wrap jdtls diagnostic processing so custom diagnostics always publish
- Add configurable
suppressJdtlsPatternsin.java-functional-lsp.json - Error handling on all
_analyze_and_publish()call sites - Version bump to 0.8.0
Full Changelog: v0.7.9...v0.8.0
v0.7.9
feat: add Lombok support with auto-discovery and false-positive filtering
- Auto-discover Lombok agent from project config, env var, Maven cache, or dedicated dir
- Pass as -javaagent to jdtls for proper annotation processing (@builder, @value, @slf4j, @DaTa)
- Filter Lombok false-positive diagnostics when agent not found (narrow regex, no real errors suppressed)
- Semantic version sorting for Maven cache discovery
- 14 new tests for Lombok support
v0.7.8
fix: module-scoped data-dir to avoid loading stale monorepo index
Each module now gets its own jdtls data directory instead of sharing a single 2.5GB monorepo index. This enables fast cold starts (~10s) for on-demand module loading.
v0.7.7
fix: remove eager workspace expansion that negated module-scoping
- Remove eager workspace expansion that undid module-scoping optimization
- Gate READY signal on publishDiagnostics (reliable indexing-complete signal)
- Add startup retry with 5-minute cooldown for transient failures
v0.7.6
fix: skip non-Java URIs in jdtls diagnostics callback
jdtls publishes diagnostics for directory URIs and build files during workspace initialization. The callback tried to read these as text documents, causing [Errno 21] Is a directory errors. Only run custom analysis on .java URIs.
v0.7.5 — restore 120s initialize timeout
Fix: restore 120s timeout for jdtls initialize handshake.
Even module-scoped init can take >30s when the module has heavy Maven dependencies that need classpath resolution on first cold start. _INITIALIZE_TIMEOUT = 120s applies only to the initialize request; normal request timeout stays at 30s.
brew upgrade java-functional-lspv0.7.4 — lazy module-scoped jdtls with adaptive waiting
Features
Lazy module-scoped jdtls initialization
jdtls no longer blocks on startup. First didOpen → finds nearest pom.xml/build.gradle → starts jdtls scoped to that module (~2-3s vs 30-120s). Custom diagnostics publish immediately.
Incremental module loading
Each new file open adds its module via workspace/didChangeWorkspaceFolders. Full workspace expands in the background.
Demand-driven module prioritization (ModuleRegistry)
When hover/definition/references targets an unloaded module:
- READY → forward instantly (zero overhead)
- UNKNOWN → add module, try, wait adaptively via
asyncio.Event, retry - ADDED → try, wait, retry
First success fires Event.set() — all waiting coroutines wake instantly. No fixed sleep.
Dynamic jdtls capability registration
hover/definition/references/completion/documentSymbol registered only after jdtls starts. IDE diagnostic tooltips never suppressed.
Numbers
- 361 tests, 84% coverage
- Custom diagnostics: immediate (< 1s)
- jdtls features: ~2-3s (was 30-120s)
Upgrade
brew upgrade java-functional-lsp
# or
pip install --upgrade java-functional-lsp