Add graalvm-native-images: Boot 4.1 + GraalVM CE for JDK 25, AOT processing,

the tracing agent, and a real reflection-collision trap

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EQNA6DJ9VgCtW6zhCE8Xud
This commit is contained in:
Claude
2026-09-20 11:03:09 +00:00
parent e4b5636f7c
commit 8cdfcd4d8d
23 changed files with 627 additions and 0 deletions
@@ -0,0 +1,46 @@
# 01 — Versions and setup
[Back to README →](../README.md) | [Next: 02 — building the image →](02-building-the-image.md)
## The version this project's own earlier post got wrong
The previous version of the linked post assumed Spring Boot 3.x, JDK 17, and "GraalVM 22.3" --
installed the old way, via `sdk install java 22.3.r17-grl` followed by a separate
`gu install native-image` step.
Checked directly rather than assumed:
- **GraalVM ships `native-image` bundled by default now.** Downloading GraalVM Community Edition
for JDK 25 (build 25.0.2, verified by downloading it from
`github.com/graalvm/graalvm-ce-builds/releases/download/jdk-25.0.2/...` and running
`native-image --version`) and checking `$JAVA_HOME/bin/` shows `native-image`,
`native-image-configure`, and `jnativescan` already present. The `gu install native-image` step
the old post described was retired years ago; running it against a current GraalVM distribution
fails because the `gu` tool itself was removed.
- **The current official docs' local-build command is `mvn -Pnative native:compile`**, not
`./mvnw clean package -Pnative` (what the old post used). Chapter 02 shows exactly why that
distinction matters -- `package` alone silently does not invoke the GraalVM compiler at all in
this verified setup.
- **`spring-boot-starter-parent:4.1.1` already wires up `native-maven-plugin` with zero extra
configuration.** The old post's manual `<profile>` block, hardcoded `<native-buildtools.version>`
property, and explicit `<mainClass>` are all unnecessary now -- this project's
[pom.xml](../pom.xml) needs only a bare `<profile><id>native</id>` with the plugin declared and
no version, and `mvn help:effective-pom -Pnative` confirms Maven resolves it to version 1.1.8,
which is what `spring-boot-starter-parent` pins via its own dependency management (1.1.14 is the
newest release on Maven Central as of this writing, per `native-maven-plugin`'s
`maven-metadata.xml`, but the parent's pinned version is what actually runs unless you override
it).
## What this project pins, and why
| | Version | Checked how |
|---|---|---|
| Spring Boot | 4.1.1 | Matches the rest of this repository's other chapters |
| JDK for JVM runs | Temurin 25.0.4.1 | `java -version` |
| GraalVM for native builds | Community Edition for JDK 25, build 25.0.2+10.1 | Downloaded directly, `native-image --version` |
| `native-maven-plugin` | 1.1.8 | `mvn help:effective-pom -Pnative`; Maven Central's `maven-metadata.xml` lists 1.1.14 as newest, confirming 1.1.8 is a deliberate, slightly older pin from Spring Boot's own dependency management, not the newest available |
A plain JDK (Temurin, in `$JDK25_HOME`) is enough for every JVM-mode measurement in this project.
Only the native-image build itself needs the separate GraalVM distribution in `$GRAALVM_HOME`
(see [scripts/run-all.sh](../scripts/run-all.sh)) -- and switching `JAVA_HOME` back and forth
between the two is the only genuinely fiddly part of the whole setup.