Skip to content

Releases: aviadshiber/java-functional-lsp

v0.9.1

14 Apr 13:43

Choose a tag to compare

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_publish no longer logs ERROR: Error re-publishing diagnostics for 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 didOpen events are diagnosable.

v0.9.0

14 Apr 09:42
26b36db

Choose a tag to compare

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 via workspace/didChangeWatchedFiles, triggering an incremental rebuild instead of a full cold-start re-index
    • Tracks *.java + pom.xml / build.gradle / build.gradle.kts per 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

v0.8.1

13 Apr 20:00
688f8c4

Choose a tag to compare

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.name and 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-register debug 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-lsp

After upgrading, restart IntelliJ — diagnostics should appear automatically. Server logs will show: JetBrains IDE detected (...) — skipping jdtls proxy.

v0.8.0

13 Apr 12:54
99f4984

Choose a tag to compare

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 (.version marker)
  • 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 suppressJdtlsPatterns in .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

13 Apr 10:53
0530923

Choose a tag to compare

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

12 Apr 17:15
782804c

Choose a tag to compare

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

11 Apr 20:24
9f67d6c

Choose a tag to compare

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

11 Apr 19:05
9235820

Choose a tag to compare

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

11 Apr 18:06
ff0f3f2

Choose a tag to compare

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-lsp

v0.7.4 — lazy module-scoped jdtls with adaptive waiting

11 Apr 16:48
a239874

Choose a tag to compare

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