🔴 The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOG2026-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)

Solution 1✓ Most common cause

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 { ... }
Solution 2

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); } }
Solution 3

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.jar
Solution 4

Update 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>
Solution 5

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

Spring Boot 2.x

Native image support was experimental and required manual reflect-config.json files.

Spring Boot 3.x

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.