Quarkus core components - runtime library for the Cloud Native, Container First Java framework
—
The Native Image Support capability provides registration systems for GraalVM native image compilation, including reflection and dynamic proxy support.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RegisterForReflection {
/**
* Register methods for reflection access.
* @return true to register methods (default: true)
*/
boolean methods() default true;
/**
* Register fields for reflection access.
* @return true to register fields (default: true)
*/
boolean fields() default true;
/**
* Skip nested classes during registration.
* @return true to ignore nested classes (default: false)
*/
boolean ignoreNested() default false;
/**
* Alternative target classes to register instead of annotated class.
* @return Array of classes to register
*/
Class<?>[] targets() default {};
/**
* Target class names when classes are not available at compile time.
* @return Array of class names to register
*/
String[] classNames() default {};
/**
* Register for serialization support.
* @return true to enable serialization support (default: false)
*/
boolean serialization() default false;
/**
* Register the complete class hierarchy.
* @return true to register full hierarchy (default: false)
*/
boolean registerFullHierarchy() default false;
/**
* Mark allocated instances as unsafe.
* @return true to mark as unsafe allocated (default: false)
*/
boolean unsafeAllocated() default false;
/**
* Lambda capturing types for registration.
* @return Array of lambda capturing type names
*/
String[] lambdaCapturingTypes() default {};
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RegisterForProxy {
/**
* Interface classes to register for dynamic proxy creation.
* @return Array of interface classes
*/
Class<?>[] value() default {};
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Register current class for reflection
@RegisterForReflection
public class MyReflectiveClass {
private String privateField;
public int publicField;
private void privateMethod() {
// This method will be accessible via reflection
}
public void publicMethod() {
// This method will be accessible via reflection
}
}import io.quarkus.runtime.annotations.RegisterForReflection;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.ArrayList;
// Register external classes for reflection
@RegisterForReflection(targets = {
ObjectMapper.class,
HashMap.class,
ArrayList.class
})
public class ReflectionConfig {
// This class serves as a configuration holder
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Register classes by name (useful when classes might not be on classpath)
@RegisterForReflection(classNames = {
"com.example.DynamicallyLoadedClass",
"org.external.library.SomeClass",
"java.util.concurrent.ThreadPoolExecutor"
})
public class ClassNameBasedRegistration {
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Register only fields, not methods
@RegisterForReflection(
methods = false,
fields = true
)
public class FieldOnlyReflection {
private String data;
private int count;
// Methods will not be registered for reflection
public void someMethod() {
}
}
// Register only methods, not fields
@RegisterForReflection(
methods = true,
fields = false
)
public class MethodOnlyReflection {
// Fields will not be registered for reflection
private String data;
public void reflectiveMethod() {
// This method will be accessible via reflection
}
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Base class
public abstract class BaseEntity {
protected Long id;
protected String name;
public abstract void process();
}
// Register full hierarchy
@RegisterForReflection(registerFullHierarchy = true)
public class ConcreteEntity extends BaseEntity {
private String specificData;
@Override
public void process() {
// Implementation
}
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Register for serialization (includes all necessary reflection metadata)
@RegisterForReflection(serialization = true)
public class SerializableData implements Serializable {
private String name;
private int value;
private List<String> items;
// Getters and setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getValue() { return value; }
public void setValue(int value) { this.value = value; }
public List<String> getItems() { return items; }
public void setItems(List<String> items) { this.items = items; }
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Include nested classes in registration
@RegisterForReflection(ignoreNested = false)
public class OuterClass {
private String outerField;
public static class StaticNestedClass {
private String nestedField;
}
public class InnerClass {
private String innerField;
}
}
// Exclude nested classes from registration
@RegisterForReflection(ignoreNested = true)
public class OuterClassExcludeNested {
private String outerField;
// These nested classes will NOT be registered
public static class NotRegistered {
private String field;
}
}import io.quarkus.runtime.annotations.RegisterForProxy;
// Define interfaces
public interface UserService {
User findById(Long id);
List<User> findAll();
}
public interface PaymentService {
Payment processPayment(PaymentRequest request);
}
// Register interfaces for dynamic proxy creation
@RegisterForProxy({UserService.class, PaymentService.class})
public class ProxyConfiguration {
}
// Usage with dynamic proxies
public class ServiceProxyFactory {
public <T> T createProxy(Class<T> serviceInterface, InvocationHandler handler) {
return (T) Proxy.newProxyInstance(
serviceInterface.getClassLoader(),
new Class<?>[]{serviceInterface},
handler
);
}
public UserService createUserServiceProxy() {
return createProxy(UserService.class, (proxy, method, args) -> {
// Custom proxy logic
System.out.println("Invoking method: " + method.getName());
// Delegate to actual implementation or perform custom logic
return null;
});
}
}import io.quarkus.runtime.annotations.RegisterForReflection;
import com.fasterxml.jackson.annotation.JsonProperty;
// Register DTOs for JSON serialization/deserialization
@RegisterForReflection
public class UserDto {
@JsonProperty("user_id")
private Long id;
@JsonProperty("user_name")
private String name;
@JsonProperty("email_address")
private String email;
// Constructors
public UserDto() {}
public UserDto(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// Getters and setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
// Register collection of related DTOs
@RegisterForReflection(targets = {
UserDto.class,
AddressDto.class,
ContactDto.class
})
public class DtoRegistration {
}import io.quarkus.runtime.annotations.RegisterForReflection;
import jakarta.persistence.*;
// Register JPA entities for reflection
@RegisterForReflection(registerFullHierarchy = true)
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "username", unique = true, nullable = false)
private String username;
@Column(name = "email")
private String email;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Order> orders = new ArrayList<>();
// Constructors, getters, setters
public User() {}
public User(String username, String email) {
this.username = username;
this.email = email;
}
// Getters and setters...
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Register classes based on configuration
@RegisterForReflection(classNames = {
// Database drivers
"org.postgresql.Driver",
"org.h2.Driver",
// Third-party libraries
"org.apache.commons.lang3.StringUtils",
"org.apache.commons.collections4.CollectionUtils",
// Custom application classes
"com.mycompany.app.domain.User",
"com.mycompany.app.domain.Order"
})
public class LibraryReflectionConfig {
}import io.quarkus.runtime.annotations.RegisterForReflection;
// Register different classes based on build profiles
public class ConditionalReflectionConfig {
// For development/test environments
@RegisterForReflection(targets = {
TestDataBuilder.class,
MockService.class
})
public static class DevelopmentReflectionConfig {
}
// For production environments
@RegisterForReflection(targets = {
ProductionService.class,
CacheManager.class
})
public static class ProductionReflectionConfig {
}
}import io.quarkus.runtime.annotations.RegisterForReflection;
import io.quarkus.runtime.annotations.RegisterForProxy;
// Register Spring Framework classes (if using Spring compatibility)
@RegisterForReflection(classNames = {
"org.springframework.beans.factory.annotation.Autowired",
"org.springframework.stereotype.Service",
"org.springframework.web.bind.annotation.RestController"
})
public class SpringCompatibilityRegistration {
}
// Register interfaces for CDI proxies
@RegisterForProxy({
jakarta.enterprise.context.ApplicationScoped.class,
jakarta.enterprise.context.RequestScoped.class
})
public class CdiProxyRegistration {
}targets parameter to register multiple related classes in one placeclassNames for optional dependencies that might not be presentserialization only when needed for performanceregisterFullHierarchy carefully as it can register many classesWhen encountering reflection issues in native images:
-H:+PrintAnalysis@RegisterForReflection to explicitly register missing classesregisterFullHierarchy for complex class hierarchiesInstall with Tessl CLI
npx tessl i tessl/maven-io-quarkus--quarkus-core