Skip to content

Detect and verify JVM AOT cache recording during integration tests - #37124

Open
vpelikh wants to merge 2 commits into
spring-projects:mainfrom
vpelikh:GH-36774
Open

Detect and verify JVM AOT cache recording during integration tests#37124
vpelikh wants to merge 2 commits into
spring-projects:mainfrom
vpelikh:GH-36774

Conversation

@vpelikh

@vpelikh vpelikh commented Aug 10, 2026

Copy link
Copy Markdown

Introduce AotCacheTestExecutionListener, registered by default in the TestContext framework. It activates automatically when the test JVM is started with AOT cache recording enabled via the JDK 25+ single-step -XX:AOTCacheOutput=<path> flag, injected by the Spring Boot Maven or Gradle plugins.

The JVM performs the actual cache generation. This listener coordinates the training run and verifies the outcome:

  • Validates the JDK version (JDK 25+, JEP 514).
  • Eagerly loads the ApplicationContext so that context creation is captured as part of the training workload.
  • Warns when the application class loader is not a standard JDK class loader (AOT cache only caches classes loaded by JDK built-in class loaders).
  • Warns when -Dspring.context.exit=onRefresh is set, since it would terminate the test JVM mid-run.
  • Verifies on JVM exit that the cache file was produced at the path specified by the -XX:AOTCacheOutput flag.

Why

This PR is part of #36774. Generating the JVM AOT cache from integration tests lets a realistic test suite exercise a broader portion of the application's startup and request-handling workflow than a simple -Dspring.context.exit=onRefresh run, producing a more effective cache. The cache also stores method profiling information, so exercising realistic code paths improves warmup behavior as well.

How it works

  • No Spring configuration or property is required: the JVM flags are the single source of truth for whether recording is enabled and where the cache is written. The listener only detects flags via RuntimeMXBean.getInputArguments().
  • By convention, the cache is written to aot-cache/application.aot relative to the test working directory, matching the location detected by the Paketo Spring Boot buildpack and bundled into the image by the Spring Boot build plugins.
  • The listener is registered by default and is a no-op unless AOT cache recording is enabled, so it does not affect regular test runs.

Documentation

  • integration/aot-cache.adoc: new "Generating the cache from integration tests" section.
  • testcontext-framework/tel-config.adoc and TestExecutionListener javadoc: added the listener to the default listener list.

Notes

  • JDK 24 is not supported. It is not an LTS release and it has a different flow for AOT cache generation (JEP 483), so it's not worth adding support for it now; it can be done as a follow-up if needed.

Related PRs

Introduce an AotCacheTestExecutionListener that is registered by default
and activates automatically when the test JVM is started with AOT cache
recording enabled via the JDK 25+ -XX:AOTCacheOutput=<path> flag
(injected by the Spring Boot Maven or Gradle plugins).

When active, the listener validates the JDK version and the application
class loader, eagerly loads the ApplicationContext so that context
creation is captured as part of the training workload, warns if
spring.context.exit=onRefresh is set, and verifies on JVM exit that the
cache file was produced at the path specified by the -XX:AOTCacheOutput
flag.

Signed-off-by: Vasily Pelikh <2010720+vpelikh@users.noreply.github.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Aug 10, 2026
@vpelikh

vpelikh commented Aug 10, 2026

Copy link
Copy Markdown
Author

CC @sdeleuze

@sbrannen sbrannen added in: test Issues in the test module theme: aot An issue related to Ahead-of-time processing labels Aug 12, 2026
Update TestExecutionListenersTests to include the new
AotCacheTestExecutionListener in the expected default listener lists, and
remove an unused jspecify NonNull import from
AotCacheTestExecutionListenerTests that failed checkstyle.

Signed-off-by: Vasily Pelikh <2010720+vpelikh@users.noreply.github.com>
@vpelikh

vpelikh commented Aug 12, 2026

Copy link
Copy Markdown
Author

Fixed CI failures in 57d0ee0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in: test Issues in the test module status: waiting-for-triage An issue we've not yet triaged or decided on theme: aot An issue related to Ahead-of-time processing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants