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
3.0 KiB
GraalVM native images of a Spring Boot 4.1 application
Companion project for GraalVM Native Images for Spring Boot 4.1: AOT Processing, the Tracing Agent, and a Real Reflection Failure on ankurm.com.
A small Spring Boot 4.1 web app, built and run three ways -- a plain java -jar, the same jar
with Spring's AOT processing applied, and a GraalVM native image -- with every startup time,
memory number, and failure message in this README and the linked post captured from a real run,
not estimated.
Versions
| Spring Boot | 4.1.1 |
| JDK (JVM runs) | Temurin 25.0.4.1 |
| GraalVM (native builds) | GraalVM Community Edition for JDK 25, build 25.0.2+10.1 |
native-maven-plugin |
1.1.8 (pinned by spring-boot-starter-parent:4.1.1's dependency management; 1.1.14 is the latest on Maven Central as of this writing, but the parent's pinned version is what actually runs unless overridden) |
The previous version of this project and its post assumed Spring Boot 3.x, JDK 17, and GraalVM 22.3 -- two major generations behind. See docs/01-versions-and-setup.md for how each version claim here was checked.
Quickstart
# 1. Plain JVM run (any JDK 25 build)
mvn -DskipTests package
java -jar target/app.jar
# 2. Native image (needs a GraalVM distribution -- native-image ships bundled, no `gu install` step)
export JAVA_HOME=/path/to/graalvm-25.0.2
mvn -Pnative -DskipTests native:compile # NOT `mvn -Pnative package` -- see docs/02-building-the-image.md
./target/graalvm-native-images
What's in this chapter
| Doc | Covers |
|---|---|
| 01-versions-and-setup.md | Verified version claims; why gu install native-image is obsolete |
| 02-building-the-image.md | AOT processing's real generated output; why -Pnative package alone does not build a native image |
| 03-the-reflection-trap.md | A real ClassNotFoundException from a runtime-computed Class.forName, the tracing-agent fix, and the metadata-collision trap that fix runs into |
| 04-honest-limits.md | What native images cost you, and where Project Leyden fits as the non-full-native alternative |
Every number quoted in the post is in docs/output/ as a trimmed, real transcript.
Measured, not estimated
| plain JVM | native image | |
|---|---|---|
| Startup ("Started ... in") | 3.472 s | 0.091 s (0.104 s with reflection hints added) |
| RSS at idle | ~190.8 MB | ~105.5 MB |
| Artifact size | 22 MB jar (+ a JDK install) | 93 MB self-contained executable |
| Build time | ordinary mvn package |
4m 14s–4m 19s on 2 vCPU / 8 GB |
Full transcripts: docs/output/01-jvm-baseline.txt, docs/output/02-native-build.txt, docs/output/05-native-startup-fixed.txt.