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:
@@ -0,0 +1,53 @@
|
||||
# 02 — AOT processing, and why `package` alone doesn't build the image
|
||||
|
||||
[← Previous: 01 — versions and setup](01-versions-and-setup.md) | [Back to README →](../README.md) | [Next: 03 — the reflection trap →](03-the-reflection-trap.md)
|
||||
|
||||
## What Spring's AOT processing actually generates
|
||||
|
||||
`mvn spring-boot:process-aot` (bound to the `package` phase automatically, no profile needed) is
|
||||
what makes a Spring Boot native image possible at all -- it runs the application's startup logic
|
||||
once, at build time, and writes down what it learns as plain Java source instead of leaving it to
|
||||
be rediscovered by reflection at every future startup. On this project it produced, in
|
||||
`target/spring-aot/main/`:
|
||||
|
||||
- **95 generated `.java` source files** -- one `*__BeanDefinitions.java` per auto-configuration
|
||||
class and application bean, including
|
||||
[`HelloController__BeanDefinitions.java`](../src/main/java/com/ankurm/graalvmdemo/HelloController.java)
|
||||
and `ReportController__BeanDefinitions.java`, plus a
|
||||
`GraalvmDemoApplication__ApplicationContextInitializer.java` that builds the whole
|
||||
`ApplicationContext` as ordinary Java calls instead of classpath scanning.
|
||||
- **`META-INF/native-image/com.ankurm/graalvm-native-images/reachability-metadata.json`** -- the
|
||||
unified reflection/resource/proxy configuration format GraalVM now uses (a single file, not the
|
||||
older separate `reflect-config.json` / `resource-config.json` / `proxy-config.json` trio).
|
||||
- **`native-image.properties`** -- build arguments the plugin feeds straight to `native-image`.
|
||||
|
||||
## Why `mvn -Pnative package` alone does not produce a binary
|
||||
|
||||
Reflected in this exact setup, not assumed: running `mvn -Pnative -DskipTests package` completes
|
||||
in under nine seconds and its log contains `add-reachability-metadata`, `process-aot`, `jar`, and
|
||||
`repackage` -- and nothing else. Grepping that log for `native-image` or `Generating '` returns
|
||||
zero matches. `mvn help:effective-pom -Pnative` confirms why: the `native` profile this project
|
||||
(and a default Spring Initializr project) declares binds *no* execution of its own to any phase --
|
||||
it only adds the plugin so its own `add-reachability-metadata` goal, bound in the plugin's own
|
||||
metadata, participates in the build. The goal that actually invokes the GraalVM compiler,
|
||||
`native:compile`, has to be run explicitly:
|
||||
|
||||
```
|
||||
mvn -Pnative -DskipTests native:compile
|
||||
```
|
||||
|
||||
which matches Spring's own current documentation for local (non-Docker) native builds. The
|
||||
`./mvnw clean package -Pnative` command in tutorials and in the earlier version of this project's
|
||||
post does not do this -- confirmed by testing it directly, not by reading the plugin's changelog.
|
||||
Full transcripts of both runs, side by side:
|
||||
[docs/output/06-package-does-not-compile-native.txt](output/06-package-does-not-compile-native.txt)
|
||||
and [docs/output/02-native-build.txt](output/02-native-build.txt).
|
||||
|
||||
## The build itself, measured
|
||||
|
||||
On this project's 2 vCPU / 8 GB build machine, `native-image` analysis found 20,126 reachable
|
||||
types across 29,154 fields and 91,938 methods, registered 7,495 types for reflection, and finished
|
||||
in 4 minutes 14 seconds to 4 minutes 19 seconds across repeated runs, peaking at 4.36 GB resident
|
||||
memory during compilation. The resulting executable is 93 MB, versus a 22 MB jar that still needs
|
||||
a JRE installed alongside it to run at all. Full transcript:
|
||||
[docs/output/02-native-build.txt](output/02-native-build.txt).
|
||||
Reference in New Issue
Block a user