| name | quarkus-native |
| description | Deep expertise in Quarkus Native Image builds, GraalVM integration, reflection configuration, and Profile-Guided Optimization. Use for native compilation questions. |
| version | 1.0.0 |
| keywords | ["quarkus","native-image","graalvm","aot","native","optimization"] |
quarkus-native
Keyword: quarkus-native | Platforms: gemini,claude,codex
Quarkus Native Image Expert Skill - Specialized in building, optimizing, and troubleshooting native executables for Quarkus applications.
Core Mandates
- Closed-World Awareness: All classes, methods, and resources must be known at build time.
- Reflection Explicit: Register all reflection usage via
@RegisterForReflection or reflection-config.json.
- Resource Registration: All runtime resources must be declared in
resource-config.json.
- Build-Time Initialization: Prefer build-time initialization for faster startup; use runtime init only for side-effect classes.
- Test in Native Mode: Always run
@QuarkusIntegrationTest against the native binary before production.
Quick Start: Native Build
Maven
./mvnw package -Dnative
./mvnw package -Dnative -Dquarkus.native.container-build=true
./mvnw verify -Pnative
Gradle
./gradlew build -Dquarkus.package.type=native
./gradlew build -Dquarkus.package.type=native -Dquarkus.native.container-build=true
Bazel (rules_quarkus)
bazel build //:myapp_native
bazel build //:myapp_native \
--@rules_quarkus//native:builder_image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-21
Quarkus Native Configuration
Essential Properties
# === Build Type ===
quarkus.package.type=native
# === Container Build (Recommended) ===
quarkus.native.container-build=true
quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-21
# === Memory ===
quarkus.native.native-image-xmx=8g
# === Debugging ===
quarkus.native.additional-build-args=-H:+ReportExceptionStackTraces
# === Reports ===
quarkus.native.enable-reports=true
# Generates: target/reports/call_tree_*.txt, target/reports/reachable_methods.txt
Profile-Specific Native Config
# application.properties
%prod.quarkus.package.type=native
%prod.quarkus.native.container-build=true
%prod.quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-21
# Development (JVM mode for fast startup)
%dev.quarkus.package.type=jar
# Test (native for integration tests)
%test.quarkus.package.type=native
Builder Images
| Image | JDK | Size | Use Case |
|---|
ubi-quarkus-mandrel-builder-image:jdk-21 | 21 | Medium | General purpose |
ubi-quarkus-graalvmce-builder-image:jdk-21 | 21 | Large | GraalVM CE with all features |
ubi-quarkus-mandrel-builder-image:jdk-21.0.2.0-Final-java21 | 21 | Medium | Specific Mandrel version |
Reflection Configuration
@RegisterForReflection (Recommended)
@RegisterForReflection
public class UserDto {
private String name;
private String email;
}
@RegisterForReflection(targets = { UserDto.class, OrderDto.class })
public class ReflectionConfig {
}
@RegisterForReflection(fields = false, methods = true)
public class ApiResponse {
public String status;
public Object data;
}
reflection-config.json
[
{
"name": "com.example.UserDto",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true
},
{
"name": "com.example.OrderDto",
"methods": [
{ "name": "getId", "parameterTypes": [] },
{ "name": "setId", "parameterTypes": ["java.lang.Long"] }
],
"fields": [
{ "name": "status" }
]
}
]
Native Image Agent (Auto-Generate)
./mvnw test -Dquarkus.native.agent.enabled=true
java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image \
-jar target/quarkus-app/quarkus-run.jar
java -agentlib:native-image-agent=config-merge-dir=src/main/resources/META-INF/native-image \
-jar target/quarkus-app/quarkus-run.jar
Resource Configuration
resource-config.json
{
"resources": {
"includes": [
{ "pattern": "\\Qapplication.properties\\E" },
{ "pattern": "\\Qdb/migration/.*\\E" },
{ "pattern": "\\QMETA-INF/.*\\E" },
{ "pattern": "\\Qtemplates/.*\\E" }
],
"excludes": [
{ "pattern": "\\Q*.test\\E" }
]
},
"bundles": [
{ "name": "messages" },
{ "name": "ValidationMessages" }
]
}
Quarkus Resource Registration
# Register resources in application.properties
quarkus.native.resources.includes=db/migration/.*,templates/.*
quarkus.native.resources.excludes=*.test,*.dev
Initialization Configuration
Build-Time vs Runtime Initialization
# application.properties
quarkus.native.additional-build-args=\
--initialize-at-build-time=com.example.ConfigClass,\
--initialize-at-run-time=com.example.NetworkClient,\
--trace-class-initialization=com.example.*
Common Initialization Patterns
@io.quarkus.runtime.annotations.RegisterForReflection
public class BuildTimeConfig {
public static final String VERSION = "1.0.0";
}
public class RuntimeConfig {
static {
System.loadLibrary("native-lib");
}
}
Profile-Guided Optimization (PGO)
Step-by-Step PGO
./mvnw package -Dnative \
-Dquarkus.native.additional-build-args=--pgo-instrument
./target/myapp-1.0.0-SNAPSHOT-runner
./mvnw package -Dnative \
-Dquarkus.native.additional-build-args=--pgo=default.iprof
PGO with Custom Profile Name
./mvnw package -Dnative \
-Dquarkus.native.additional-build-args=--pgo-instrument=myapp.iprof
./target/myapp-1.0.0-SNAPSHOT-runner
./mvnw package -Dnative \
-Dquarkus.native.additional-build-args=--pgo=myapp.iprof
Native Image Testing
@QuarkusIntegrationTest
@QuarkusIntegrationTest
class NativeUserResourceIT {
@Test
void shouldListUsers() {
given()
.when().get("/api/users")
.then()
.statusCode(200);
}
@Test
void shouldCreateUser() {
given()
.contentType(ContentType.JSON)
.body("{\"name\": \"Alice\", \"email\": \"alice@example.com\"}")
.when().post("/api/users")
.then()
.statusCode(201);
}
}
Conditional Native Testing
@QuarkusTest
class UserResourceTest {
@Test
@DisabledOnNativeImage
void shouldTestDevOnlyFeature() {
}
@Test
@EnabledOnNativeImage
void shouldTestNativeOnlyFeature() {
}
}
Troubleshooting Decision Tree
Native build failed?
├── "ClassNotFoundException" at runtime
│ └── Missing reflection config
│ ├── Add @RegisterForReflection to the class
│ ├── Add to reflection-config.json
│ └── Run with native-image agent
├── "NoSuchMethodException" at runtime
│ └── Missing method in reflection config
│ └── Add method to reflection-config.json
├── "MissingResourceException"
│ └── Resource not included in native image
│ ├── Add to resource-config.json
│ └── Use quarkus.native.resources.includes
├── "UnsupportedFeatureError"
│ └── Using unsupported JVM feature
│ ├── Check GraalVM limitations
│ └── Use --report-unsupported-elements-at-runtime
├── "OutOfMemoryError" during build
│ └── Increase build memory
│ └── quarkus.native.native-image-xmx=8g (or 12g)
├── Build timeout
│ └── Increase timeout or use more powerful machine
│ └── quarkus.native.additional-build-args=--timeout=600
└── "Image build request failed"
└── Docker/container issues
└── Check Docker daemon, pull builder image manually
Common Errors & Fixes
| Error | Cause | Fix |
|---|
ClassNotFoundException | Missing reflection config | Add @RegisterForReflection or reflect-config.json |
NoSuchMethodException | Method not in reflection config | Add method to reflect-config.json |
MissingResourceException | Resource not included | Add to resource-config.json |
IllegalArgumentException: Proxy | Missing proxy config | Add to proxy-config.json |
OutOfMemoryError | Insufficient build memory | Increase quarkus.native.native-image-xmx |
UnsupportedFeatureError | Unsafe/JNI usage | Use --report-unsupported-elements-at-runtime |
Image build request failed | Docker not running | Start Docker daemon |
Build timeout | Complex application | Increase timeout, use more memory |
Optimization Strategies
Reducing Image Size
# Remove unused beans
quarkus.native.remove-unused-beans=true
# Remove metadata for smaller image
quarkus.native.enable-reports=false
# Exclude unnecessary resources
quarkus.native.resources.excludes=*.md,*.txt
Improving Startup Time
# Use SerialGC for small heaps (default for native)
quarkus.native.additional-build-args=--gc=serial
# Or G1GC for larger heaps
quarkus.native.additional-build-args=--gc=G1
# Enable PGO for better performance
quarkus.native.additional-build-args=--pgo=default.iprof
Memory Tuning
# Set max heap for native image
quarkus.native.additional-build-args=-R:MaxHeapSize=256m
# Set initial heap
quarkus.native.additional-build-args=-R:MinHeapSize=64m
Bazel Native Build
BUILD.bazel for Native Image
load("@rules_quarkus//quarkus:defs.bzl", "quarkus_application")
quarkus_application(
name = "myapp_native",
srcs = glob(["src/main/java/**/*.java"]),
resources = glob(["src/main/resources/**"]),
deps = [
"//common/utils",
"@maven//:io_quarkus_quarkus_core",
"@maven//:io_quarkus_quarkus_rest",
],
native = True,
native_image_xmx = "8g",
additional_build_args = [
"-H:+ReportExceptionStackTraces",
"--initialize-at-build-time=com.example.Config",
],
)
References
Skill Interoperability
The quarkus-native skill specializes in:
- graalvm-expert 🚀: Core GraalVM Native Image knowledge.
- quarkus-expert ⚡: Quarkus-specific native build configuration.
- rules-quarkus 🔧: Bazel integration for native builds.