Add aot-cache module: the JDK 25 AOT cache on Spring Boot 4.1 vs AppCDS, Spring AOT and GraalVM native

A Spring Boot 4.1.1 order service started 12 ways (plain and extracted jar, Spring AOT output, AppCDS, AOT cache trained with and without traffic, JDK 27, native image), ten interleaved rounds each, with first-request latency; 24 cache-mismatch cases; Docker layer arithmetic. Transcripts are in output/ (no docs/ folder).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
This commit is contained in:
Claude
2026-09-24 16:44:16 +00:00
parent fa4205f631
commit 3e2029ab3a
30 changed files with 1023 additions and 1 deletions
+152
View File
@@ -0,0 +1,152 @@
# cache: /home/claude/spring-boot-demo/aot-cache/work/refresh.aot, trained on JDK 25.0.4.1, extracted layout, default GC (G1), 2 CPUs
== control: the same JVM, the same jar, the same path
result: started, ready after 1987 ms (Started AotCacheApplication in 1.538 seconds)
log: (nothing at warning or error level)
== the application jar was rebuilt after a one-line code change, default AOTMode=auto
result: started, ready after 4124 ms (Started AotCacheApplication in 3.453 seconds)
log: [warning][aot] This file is not the one used while building the AOT cache: 'app.jar', timestamp has changed, size has changed
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)
log: [error ][aot] Unable to map shared spaces
== the same, with -XX:AOTMode=on
result: did not start (exit code 1)
log: [warning][aot] This file is not the one used while building the AOT cache: 'app.jar', timestamp has changed, size has changed
log: [error ][aot] shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] unrecoverable error
== a dependency jar has a different modification time (same bytes)
result: started, ready after 3865 ms (Started AotCacheApplication in 3.201 seconds)
log: [warning][aot] This file is not the one used while building the AOT cache: 'lib/spring-core-7.0.9.jar', timestamp has changed
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)
log: [error ][aot] Unable to map shared spaces
== the same files copied with plain cp (bytes and path layout identical, timestamps new)
result: started, ready after 4013 ms (Started AotCacheApplication in 3.361 seconds)
log: [warning][aot] This file is not the one used while building the AOT cache: 'app.jar', timestamp has changed
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)
log: [error ][aot] Unable to map shared spaces
== the application directory was moved after training (same bytes, different path)
result: started, ready after 2005 ms (Started AotCacheApplication in 1.542 seconds)
log: (nothing at warning or error level)
== cache trained on the fat jar, run from the extracted layout
result: started, ready after 3900 ms (Started AotCacheApplication in 3.262 seconds)
log: [warning][aot] This file is not the one used while building the AOT cache: 'app.jar', size has changed
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)
log: [error ][aot] Unable to map shared spaces
== JDK 25's cache used by JDK 27
result: started, ready after 4221 ms (Started AotCacheApplication in 3.537 seconds)
log: [warning][aot] The AOT cache version 0x13 does not match the required version 0x14.
log: [warning][aot] The AOT cache has the wrong version.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
log: [warning][aot] The AOT cache version 0x13 does not match the required version 0x14.
== the same, with -XX:AOTMode=on
result: did not start (exit code 1)
log: [warning][aot] The AOT cache version 0x13 does not match the required version 0x14.
log: [warning][aot] The AOT cache has the wrong version.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
log: [warning][aot] The AOT cache version 0x13 does not match the required version 0x14.
== -XX:+UseCompactObjectHeaders added at run time only (JDK 25)
result: started, ready after 4138 ms (Started AotCacheApplication in 3.446 seconds)
log: [warning][aot] Unable to use AOT cache.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
log: [error ][aot] Unable to map shared spaces
== a different collector at run time: -XX:+UseSerialGC
result: started, ready after 1916 ms (Started AotCacheApplication in 1.516 seconds)
log: (nothing at warning or error level)
== a different collector at run time: -XX:+UseParallelGC
result: started, ready after 1957 ms (Started AotCacheApplication in 1.473 seconds)
log: (nothing at warning or error level)
== a different collector at run time: -XX:+UseZGC
result: started, ready after 3981 ms (Started AotCacheApplication in 3.347 seconds)
log: [warning][aot] Unable to use AOT cache.
[ ] The saved state of UseCompressedOops and UseCompressedClassPointers is different from runtime, CDS will be disabled.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
log: [error ][aot] Unable to map shared spaces
== a different heap size at run time: -Xmx256m
result: started, ready after 2058 ms (Started AotCacheApplication in 1.602 seconds)
log: (nothing at warning or error level)
== a cache file that does not exist
result: started, ready after 4113 ms (Started AotCacheApplication in 3.451 seconds)
log: [error][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error][aot] Loading static archive failed.
log: [error][aot] Unable to map shared spaces
== a cache file that does not exist, with -XX:AOTMode=on
result: did not start (exit code 1)
log: [error][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error][aot] Loading static archive failed.
log: [error][aot] Unable to map shared spaces
# and on JDK 27, whose cache was trained under the default collector (G1):
== JDK 27, cache from JDK 27 (control)
result: started, ready after 1955 ms (Started AotCacheApplication in 1.547 seconds)
log: (nothing at warning or error level)
== JDK 27, -XX:+UseZGC at run time
result: started, ready after 4158 ms (Started AotCacheApplication in 3.502 seconds)
log: [warning][aot] Unable to use AOT cache.
[ ] The saved state of UseCompressedOops (1) is different from runtime (0), CDS will be disabled.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
log: [error ][aot] Unable to map shared spaces
== JDK 27, -XX:+UseSerialGC at run time
result: started, ready after 2103 ms (Started AotCacheApplication in 1.672 seconds)
log: (nothing at warning or error level)
== JDK 27, -XX:-UseCompactObjectHeaders at run time
result: started, ready after 3906 ms (Started AotCacheApplication in 3.163 seconds)
log: [warning][aot] Unable to use AOT cache.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
log: [warning][aot] Unable to use AOT cache.
log: [error ][aot] Loading static archive failed.
# why ZGC is different: ask the JVM (-Xlog:aot=info) why it refused the G1-trained cache
== JDK 27, -XX:+UseZGC with the G1-trained cache, -Xlog:aot=info
result: started, ready after 3885 ms (Started AotCacheApplication in 3.258 seconds)
log: [info][aot] The AOT cache was created with UseCompressedOops = 1, UseCompactObjectHeaders = 1
log: [warning][aot] Unable to use AOT cache.
[ ] The saved state of UseCompressedOops (1) is different from runtime (0), CDS will be disabled.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
== JDK 27, cache trained under ZGC, run under ZGC
result: started, ready after 1988 ms (Started AotCacheApplication in 1.554 seconds)
log: (nothing at warning or error level)
== JDK 27, cache trained under ZGC, run under G1 (compressed oops on again)
result: started, ready after 3869 ms (Started AotCacheApplication in 3.199 seconds)
log: [warning][aot] Unable to use AOT cache.
[ ] The saved state of UseCompressedOops (0) is different from runtime (1), CDS will be disabled.
log: [error ][aot] An error has occurred while processing the AOT cache. Run with -Xlog:aot for details.
log: [error ][aot] Loading static archive failed.
log: [warning][aot] Unable to use AOT cache.
== JDK 27, cache trained under ZGC, run under G1 with -XX:-UseCompressedOops
result: started, ready after 2018 ms (Started AotCacheApplication in 1.534 seconds)
log: (nothing at warning or error level)