gotchajavaspringMajor
GraalVM native image: reflection and dynamic proxies must be declared
Viewed 0 times
Spring Boot 3.x, GraalVM 22+
GraalVMnative imageAOTreflection hintsRuntimeHintsRegistrarSpring Boot 3native compilation
Error Messages
Problem
Compiling a Spring Boot application to a GraalVM native executable fails at runtime with ClassNotFoundException or causes silent behavior differences because native image compilation does not support runtime reflection, dynamic class loading, or JDK proxies unless they are explicitly declared.
Solution
Spring Boot 3.x has built-in GraalVM support via Ahead-of-Time (AOT) processing:
Spring's AOT engine generates reflection hints automatically for Spring-managed beans. For libraries that use reflection outside of Spring's awareness, register hints manually:
Test hint completeness with the native test task which runs tests inside the native executable.
# Build native image with Maven
./mvnw -Pnative native:compile
# Or with Gradle
./gradlew nativeCompileSpring's AOT engine generates reflection hints automatically for Spring-managed beans. For libraries that use reflection outside of Spring's awareness, register hints manually:
@Configuration
@ImportRuntimeHints(MyRuntimeHints.class)
public class AppConfig {}
class MyRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(MyDto.class,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.DECLARED_FIELDS);
hints.proxies().registerJdkProxy(MyInterface.class);
}
}Test hint completeness with the native test task which runs tests inside the native executable.
Why
GraalVM performs static analysis of all code reachable from the main entry point at compile time. Code paths discovered only at runtime (via reflection) are not included in the native executable unless declared in configuration metadata.
Gotchas
- Many popular libraries (Hibernate, Jackson, Caffeine) require GraalVM metadata — check the GraalVM Reachability Metadata repository
- Native compilation takes significantly longer than JVM compilation — use the JVM target for development and native only for production builds
- JDK proxies (Spring Security, Spring Data) are handled by Spring's AOT but third-party proxies may need manual hints
Revisions (0)
No revisions yet.