🔴 The Error You're Seeing
Confirm this matches your console output. If it does, you're in the right place.
2026-02-20 21:05:55.800 ERROR 8842 --- [ main] o.s.boot.SpringApplication : Application run failed
com.oracle.svm.core.jdk.UnsupportedFeatureError: Class com.devinhyderabad.entity.User is instantiated reflectively but was never registered. Ensure the class is registered for reflection.
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:175)⚡ Quick Fix Works 80% of the time
Add @RegisterReflectionForBinding(User.class) to a configuration class.
@Configuration
@RegisterReflectionForBinding(User.class)
public class NativeConfig { ... }🧠 Why this Happens
Tap to expand the deep technical explanation
GraalVM Native Images perform closed-world analysis at build time (AOT). They strip out any class that isn't explicitly needed. If a library (like Jackson or Hibernate) uses Java Reflection at runtime to instantiate the `User` class, GraalVM blocks it because the class wasn't registered in the native image's reflection metadata.
The HITEC City Parking Spot Analogy:
It's like a strict nightclub bouncer who only lets people in if their name is on the guest list compiled the night before. If a VIP (Reflection) tries to bring a friend (User class) who isn't on the list, the bouncer refuses entry.
🔁 How to Reproduce Confirm this is your error
Build a Spring Boot app as a GraalVM Native Image. Use a third-party library that uses `Class.forName("com.devinhyderabad.entity.User").getDeclaredConstructor().newInstance()` without providing reflection hints. Run the native binary.
🛠️ Solutions (5 Ways to Fix)
Use @RegisterReflectionForBinding
👉 Use this if you know exactly which classes need reflection.
This annotation tells Spring's AOT engine to generate reflection metadata for the specified classes during the build process.
@Configuration
@RegisterReflectionForBinding(User.class)
public class NativeConfig { ... }Implement RuntimeHints
👉 Use this if you need to register constructors, fields, or methods dynamically.
Create a class implementing `RuntimeHintsRegistrar` to programmatically register reflection hints.
@Component
public class MyHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(User.class, MemberCategory.DECLARED_FIELDS, MemberCategory.INVOKE_PUBLIC_METHODS);
}
}Run GraalVM Tracing Agent
👉 Use this if you don't know which classes a third-party library reflects upon.
Run your app on the standard JVM with the GraalVM agent attached. It watches all reflection calls and generates the `reflect-config.json` file for you.
java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/ -jar target/myapp.jarUpdate third-party libraries
👉 Use this if the library is outdated.
Older libraries don't have GraalVM metadata. Updating to a newer version often includes automatic AOT support.
<!-- Upgrade to latest version -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.2.0</version>
</dependency>Avoid reflection entirely
👉 Use this as the best practice for Native Images.
Refactor your code to use direct instantiation (`new User()`) instead of reflection. This is faster and requires zero GraalVM configuration.
// Instead of: Class.forName("User").newInstance();
// Use: User user = new User();📋 Version Notes
Native image support was experimental and required manual reflect-config.json files.
First-class AOT support. Uses @RegisterReflectionForBinding and RuntimeHints to automate metadata generation.
🛡️ How to Prevent This Next Time
When building Native Images, test early and often. Use the GraalVM tracing agent during your integration tests to capture all reflection usage automatically.