Runtime Hints for Reflection and Resources
Register reflection, proxy, and resource hints so dynamic features survive native compilation.
Why Native Images Break Reflection
GraalVM native compilation uses closed-world analysis: at build time it must see every class, method, and field that could ever be reached. Code paths it cannot statically prove are reachable are removed from the final binary.
- Reflection (
Class.forName,getDeclaredMethod) hides the target from static analysis. - Dynamic proxies generated at runtime have no class to scan at build time.
- Resources loaded via
getResourceAsStreamare not bundled unless declared.
The fix is to feed the analyzer explicit metadata called runtime hints, so it keeps these elements in the image.
What Spring Boot Contributes Automatically
Spring Boot 4 and the AOT (ahead-of-time) engine already register hints for most framework internals: @Component beans, @ConfigurationProperties classes, Jackson-bound DTOs reached through controllers, and auto-configuration classes.
You only write your own hints when you do something the AOT engine cannot trace, such as:
- Reflectively instantiating a class you load by name from config.
- Serializing a type that no controller or repository references.
- Reading a non-classpath-scanned resource file at runtime.
- Creating a JDK dynamic proxy for an interface you build yourself.
All lessons in this course
- AOT Processing and the Native Build Pipeline
- Runtime Hints for Reflection and Resources
- Class Data Sharing and JVM Startup Tuning
- Diagnosing and Fixing Native Compatibility Issues