Skip to content

Lift Java to 25 and add a GraalVM native binary - #76

Open
koppor wants to merge 6 commits into
mainfrom
feat/java-25-graalvm-native
Open

koppor wants to merge 6 commits into
mainfrom
feat/java-25-graalvm-native

Conversation

@koppor

@koppor koppor commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Two changes that belong together, each with its own ADR:

  • Java 25 (ADR 0015): maven.compiler.release goes from 17 to 25, CI and the VS Code jlink runtime build on JDK 25. Java 25 is the current LTS release, see whichjdk.com for release cadence, support windows and distributions. The IntelliJ plugin is unaffected: the 2026.1 branch of IntelliJ Community pins runtimeBuild=25.0.4, so every IDE build the plugin supports runs on JetBrains Runtime 25. Gradle stays on JDK 17 in CI, as Gradle 9.0 does not run on Java 25.
  • Native binary with GraalVM (ADR 0016): for editors without a JVM, use case vim-lsp. Released as openfasttrace-language-server-<version>-<platform> for the same five platforms as the VS Code packages.

How the native image handles reflection

ADR 0011 rejected GraalVM because LSP4J ships no Native Image metadata. Instead of a recorded reflection list that misses whatever a session did not exercise, NativeImageSupport is a GraalVM Feature that walks the classpath at image build time and registers every class of org.eclipse.lsp4j, org.tinylog and the server for reflection, plus the LanguageClient dynamic proxy. Resources and build options (--features, --no-fallback, -march=compatibility) sit in META-INF/native-image/, so native-image -jar on the standalone JAR works too.

Verified locally in a GraalVM 25 container (linux-x64): the image builds in ~27 s, is 33 MB, and .github/workflows/native_smoke_test.sh passes against doc/demo/example (initialize, published diagnostics, workspace symbols, clean exit). A GraalVM tracing-agent run of the same session recorded nothing outside the registered packages, Gson's own metadata and the ServiceLoader entries that Native Image handles itself.

Other changes

  • native Maven profile with native-maven-plugin 1.1.14; GraalVM SDK as provided dependency (stays out of the fat JAR, verified).
  • Plugin bumps needed for Java 25 class files: JaCoCo 0.8.15, Surefire 3.6.0, compiler 3.16.0, shade 3.6.2.
  • CI: new native-binary matrix job (5 platforms) using graalvm/setup-graalvm, SHA pinned; release workflow builds, downloads and uploads the binaries with sha256 files.
  • README: install section for Vim, Neovim and other editors with a vim-lsp snippet; build section for the native binary.
  • ADR 0002 marked superseded; ADR 0011 cross-references ADR 0016.

Test plan

  • mvn verify on JDK 25 locally (class files at level 69)
  • Native build and smoke test on linux-x64 in a GraalVM 25 container
  • CI native builds on linux-arm64, win32-x64, darwin-x64, darwin-arm64 (first time these run)
  • Try the binary from the CI artifact with vim-lsp

🤖 Generated with Claude Code

koppor and others added 4 commits October 10, 2026 17:17
The server is now compiled for Java 25 (ADR 0015). Nothing a user installs
depends on that any more: IntelliJ 2026.1 runs on JetBrains Runtime 25,
the VS Code extension bundles its own runtime, and the new native binary
needs none at all.

The native binary (ADR 0016) targets editors without a JVM, such as Vim
with vim-lsp. LSP4J ships no Native Image metadata, so NativeImageSupport,
a GraalVM Feature, registers every LSP4J, tinylog and server class for
reflection while the image is built and registers the LanguageClient
proxy. Resources and build options live in META-INF/native-image, so
`native-image -jar` on the standalone JAR works as well. The `native`
Maven profile builds it; CI builds and smoke tests it on all five
platforms, and the release uploads the binaries with checksums.

Gradle stays on JDK 17 in CI because Gradle 9.0 cannot run on Java 25.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
GraalVM Community for macOS on Intel ended with JDK 25.0.1, which rejects
the schema the metadata repository now serves, so the darwin-x64 build
failed. The repository only had Gson entries that the server does not
need: the smoke test passes without them. Switching it off also removes a
download from the build.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@koppor
koppor added this pull request to stack #78 October 10, 2026 17:29
@koppor
koppor marked this pull request as ready for review October 10, 2026 17:31
koppor and others added 2 commits October 10, 2026 19:33
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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