CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io--quarkus--quarkus-core-deployment

Core deployment-time APIs and infrastructure for building Quarkus applications with native image support and development-time features

Pending
Overview
Eval results
Files

packaging.mddocs/

Packaging

Quarkus packaging system handles the creation of various deployment artifacts including JAR files, native executables, container images, and specialized package formats. The packaging infrastructure supports multiple output formats optimized for different deployment scenarios from traditional JVM deployments to cloud-native container environments.

Core Imports

// Package configuration
import io.quarkus.deployment.pkg.PackageConfig;
import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.JarConfig;

// Package build items
import io.quarkus.deployment.pkg.builditem.JarBuildItem;
import io.quarkus.deployment.pkg.builditem.NativeImageBuildItem;
import io.quarkus.deployment.pkg.builditem.UberJarBuildItem;
import io.quarkus.deployment.pkg.builditem.AppCDSBuildItem;
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
import io.quarkus.deployment.pkg.builditem.ProcessInheritIODisabled;

// Package build steps
import io.quarkus.deployment.pkg.steps.JarResultBuildStep;
import io.quarkus.deployment.pkg.steps.NativeImageBuildStep;
import io.quarkus.deployment.pkg.steps.UberJarBuildStep;
import io.quarkus.deployment.pkg.steps.AppCDSBuildStep;

// Native image configuration
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem;

// Container and SBOM
import io.quarkus.deployment.images.ImageConfig;
import io.quarkus.deployment.sbom.SbomConfig;

Package Configuration

PackageConfig

Central configuration for application packaging options.

class PackageConfig {
    /**
     * Package type to create
     */
    @WithDefault("jar")
    PackageType type;
    
    /**
     * Output file name (without extension)
     */
    Optional<String> outputName;
    
    /**
     * Output directory for package
     */
    @WithDefault("target")
    String outputDirectory;
    
    /**
     * Whether to create AppCDS archive
     */
    @WithDefault("true")
    boolean createAppcds;
    
    /**
     * AppCDS configuration
     */
    AppcdsConfig appcds;
    
    /**
     * Whether to add runner suffix to JAR name
     */
    @WithDefault("true") 
    boolean addRunnerSuffix;
    
    /**
     * JAR compression configuration
     */
    JarConfig jar;
    
    /**
     * Package types supported by Quarkus
     */
    enum PackageType {
        /**
         * Standard runnable JAR with dependencies in lib/ folder
         */
        JAR,
        
        /**
         * Legacy JAR format (deprecated)
         */
        LEGACY_JAR,
        
        /**
         * Fast JAR with optimized startup (default)
         */
        FAST_JAR,
        
        /**
         * GraalVM native executable
         */
        NATIVE,
        
        /**
         * Native sources for offline compilation
         */
        NATIVE_SOURCES,
        
        /**
         * Single JAR with all dependencies included
         */
        UBER_JAR,
        
        /**
         * JAR optimized for mutable content updates
         */
        MUTABLE_JAR
    }
}

JarConfig

Configuration specific to JAR packaging.

class JarConfig {
    /**
     * Compression level for JAR entries (0-9)
     */
    @WithDefault("6")
    int compressionLevel;
    
    /**
     * Whether to compress JAR entries
     */
    @WithDefault("true")
    boolean compress;
    
    /**
     * Manifest attributes to add
     */
    Map<String, String> manifestAttributes;
    
    /**
     * Whether to include dependency list in manifest
     */
    @WithDefault("true")
    boolean addDependencyList;
    
    /**
     * User attributes in manifest
     */
    Map<String, String> userConfiguredAttributes;
}

Usage Examples:

// Configuration in application.properties
// quarkus.package.type=native
// quarkus.package.output-name=my-app
// quarkus.package.jar.compress=false

@BuildStep
void configurePackaging(PackageConfig packageConfig,
                       BuildProducer<PackageTypeBuildItem> packageType) {
    
    packageType.produce(new PackageTypeBuildItem(packageConfig.type));
    
    if (packageConfig.type == PackageType.UBER_JAR) {
        // Additional uber JAR configuration
        setupUberJarPackaging();
    }
}

JAR Packaging

JarBuildItem

Represents the built application JAR with metadata and dependencies.

class JarBuildItem extends SimpleBuildItem {
    /**
     * Path to the built JAR file
     */
    Path getPath();
    
    /**
     * Original path before any transformations
     */
    Optional<Path> getOriginalPath();
    
    /**
     * Package type of this JAR
     */
    PackageType getType();
    
    /**
     * Path to the library directory (for JAR/FAST_JAR types)
     */
    Optional<Path> getLibraryDir();
    
    /**
     * Main class specified in the JAR manifest
     */
    Optional<String> getMainClass();
    
    /**
     * Class path entries for this JAR
     */
    List<String> getClassPath();
}

UberJarBuildItem

Represents an uber JAR containing all dependencies.

class UberJarBuildItem extends SimpleBuildItem {
    /**
     * Path to the uber JAR file
     */
    Path getPath();
    
    /**
     * Original JAR path before uber JAR creation
     */
    Path getOriginalJarPath();
    
    /**
     * Size of the uber JAR in bytes
     */
    long getFileSize();
}

Usage Examples:

@BuildStep
void buildJar(ApplicationArchivesBuildItem archives,
             PackageConfig packageConfig,
             MainClassBuildItem mainClass,
             BuildProducer<JarBuildItem> jarProducer) throws IOException {
    
    Path outputDir = Paths.get(packageConfig.outputDirectory);
    String jarName = determineJarName(packageConfig, mainClass);
    Path jarPath = outputDir.resolve(jarName + ".jar");
    
    // Create JAR with manifest and dependencies
    try (JarBuilder jarBuilder = new JarBuilder(jarPath)) {
        // Add manifest
        jarBuilder.addManifest(createManifest(mainClass.getClassName()));
        
        // Add application classes
        addApplicationClasses(jarBuilder, archives.getRootArchive());
        
        // Handle dependencies based on package type
        if (packageConfig.type == PackageType.FAST_JAR) {
            Path libDir = setupLibraryDirectory(outputDir);
            copyDependencies(archives.getApplicationArchives(), libDir);
            jarProducer.produce(new JarBuildItem(jarPath, packageConfig.type, libDir));
        } else if (packageConfig.type == PackageType.UBER_JAR) {
            addDependenciesToJar(jarBuilder, archives.getApplicationArchives());
            jarProducer.produce(new JarBuildItem(jarPath, packageConfig.type));
        }
    }
}

@BuildStep(onlyIf = UberJarRequested.class)
UberJarBuildItem createUberJar(JarBuildItem jar,
                              ApplicationArchivesBuildItem archives) throws IOException {
    
    Path originalJar = jar.getPath();
    Path uberJarPath = originalJar.getParent()
        .resolve(originalJar.getFileName().toString().replace(".jar", "-uber.jar"));
    
    try (JarBuilder uberBuilder = new JarBuilder(uberJarPath)) {
        // Copy original JAR contents
        addJarContents(uberBuilder, originalJar);
        
        // Add all dependencies
        for (ApplicationArchive archive : archives.getApplicationArchives()) {
            addArchiveContents(uberBuilder, archive);
        }
    }
    
    return new UberJarBuildItem(uberJarPath, originalJar, Files.size(uberJarPath));
}

Native Image Packaging

NativeConfig

Configuration for GraalVM native image compilation.

class NativeConfig {
    /**
     * Whether native image building is enabled
     */
    @WithDefault("false")
    boolean enabled;
    
    /**
     * Additional build arguments for native-image
     */
    List<String> additionalBuildArgs;
    
    /**
     * Container image to use for building native image
     */
    @WithDefault("quay.io/quarkus/ubi-quarkus-mandrel-builder-image")
    String builderImage;
    
    /**
     * Container runtime to use for building
     */
    ContainerRuntimeConfig containerRuntime;
    
    /**
     * GraalVM installation directory
     */
    Optional<String> graalvmHome;
    
    /**
     * Java version for native image
     */
    Optional<String> javaHome;
    
    /**
     * Whether to enable debug info in native image
     */
    @WithDefault("false")
    boolean debug;
    
    /**
     * Whether to publish debug info separately
     */
    @WithDefault("false")
    boolean publishDebugBuildInfo;
    
    /**
     * Native image name
     */
    Optional<String> outputName;
    
    /**
     * Auto service loader registration
     */
    @WithDefault("false")
    boolean autoServiceLoaderRegistration;
    
    /**
     * Dump generated files during build
     */
    @WithDefault("false")
    boolean dumpProxies;
    
    /**
     * Enable all character sets
     */
    @WithDefault("false")
    boolean enableAllCharsets;
    
    /**
     * Resource configuration files
     */
    List<String> resourceConfigFiles;
}

NativeImageBuildItem

Represents the built native executable.

class NativeImageBuildItem extends SimpleBuildItem {
    /**
     * Path to the native executable
     */
    Path getPath();
    
    /**
     * Size of the native executable in bytes
     */
    long getFileSize();
    
    /**
     * GraalVM version used for compilation
     */
    Optional<String> getGraalVMVersion();
    
    /**
     * Build time in milliseconds
     */
    long getBuildTime();
    
    /**
     * Debug symbols file if generated
     */
    Optional<Path> getDebugSymbolsPath();
}

Native Image Configuration Build Items

class ReflectiveClassBuildItem extends MultiBuildItem {
    /**
     * Register class for reflection
     */
    static Builder builder(String... classNames);
    static Builder builder(Class<?>... classes);
    
    String getClassName();
    boolean isConstructors();
    boolean isMethods(); 
    boolean isFields();
    boolean isWeak();
    
    static class Builder {
        Builder constructors();
        Builder constructors(boolean constructors);
        Builder methods();
        Builder methods(boolean methods);
        Builder fields();
        Builder fields(boolean fields);
        Builder weak();
        Builder weak(boolean weak);
        ReflectiveClassBuildItem build();
    }
}

class NativeImageResourceBuildItem extends MultiBuildItem {
    /**
     * Include resources in native image
     */
    NativeImageResourceBuildItem(String... resources);
    NativeImageResourceBuildItem(List<String> resources);
    
    List<String> getResources();
}

class RuntimeInitializedClassBuildItem extends MultiBuildItem {
    /**
     * Initialize class at runtime (not build time)
     */
    RuntimeInitializedClassBuildItem(String className);
    RuntimeInitializedClassBuildItem(Class<?> clazz);
    
    String getClassName();
}

class JniRuntimeAccessBuildItem extends MultiBuildItem {
    /**
     * Enable JNI runtime access for classes
     */
    static Builder builder(String className);
    static Builder builder(Class<?> clazz);
    
    String getClassName();
    boolean isConstructors();
    boolean isMethods();
    boolean isFields();
    
    static class Builder {
        Builder constructors();
        Builder methods(); 
        Builder fields();
        JniRuntimeAccessBuildItem build();
    }
}

Usage Examples:

@BuildStep
void configureReflection(BuildProducer<ReflectiveClassBuildItem> reflection) {
    // Register classes for reflection
    reflection.produce(ReflectiveClassBuildItem.builder(
        "com.example.MyClass", 
        "com.example.MyOtherClass"
    ).constructors().methods().fields().build());
    
    // Register weak reflection (won't fail if class is missing)
    reflection.produce(ReflectiveClassBuildItem.builder("optional.Class")
        .weak().build());
}

@BuildStep  
void configureNativeResources(BuildProducer<NativeImageResourceBuildItem> resources) {
    // Include properties files
    resources.produce(new NativeImageResourceBuildItem(
        "application.properties",
        "META-INF/services/*"
    ));
    
    // Include templates and web resources
    resources.produce(new NativeImageResourceBuildItem("templates/", "static/"));
}

@BuildStep
void configureRuntimeInit(BuildProducer<RuntimeInitializedClassBuildItem> runtimeInit) {
    // Classes that must be initialized at runtime
    runtimeInit.produce(new RuntimeInitializedClassBuildItem("java.util.Random"));
    runtimeInit.produce(new RuntimeInitializedClassBuildItem("com.sun.crypto.provider.SunJCE"));
}

@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
NativeImageBuildItem buildNative(JarBuildItem jar,
                                NativeConfig nativeConfig,
                                List<ReflectiveClassBuildItem> reflectiveClasses,
                                List<NativeImageResourceBuildItem> resources) throws IOException {
    
    List<String> args = new ArrayList<>();
    args.add("-jar");
    args.add(jar.getPath().toString());
    
    // Add reflection configuration
    generateReflectionConfig(reflectiveClasses);
    args.add("-H:ReflectionConfigurationFiles=reflection-config.json");
    
    // Add resource configuration  
    generateResourceConfig(resources);
    args.add("-H:ResourceConfigurationFiles=resource-config.json");
    
    // Add user-provided arguments
    args.addAll(nativeConfig.additionalBuildArgs);
    
    // Determine output path
    Path outputPath = determineNativeImagePath(jar, nativeConfig);
    args.add("-o");
    args.add(outputPath.toString());
    
    // Execute native-image compiler
    long startTime = System.currentTimeMillis();
    executeNativeImageBuild(args);
    long buildTime = System.currentTimeMillis() - startTime;
    
    return new NativeImageBuildItem(outputPath, Files.size(outputPath), buildTime);
}

Container Integration

Container Runtime Configuration

class ContainerRuntimeConfig {
    /**
     * Container runtime to use (docker, podman)
     */
    Optional<String> executable;
    
    /**
     * Additional options for container runtime
     */
    List<String> options;
    
    /**
     * Working directory in container
     */
    @WithDefault("/project")
    String workingDirectory;
}

Image Configuration

class ImageConfig {
    /**
     * Base image for application container
     */
    @WithDefault("registry.access.redhat.com/ubi8/openjdk-17-runtime")
    String baseJvmImage;
    
    /**
     * Base image for native application container
     */
    @WithDefault("registry.access.redhat.com/ubi8/ubi-minimal")
    String baseNativeImage;
    
    /**
     * Additional JVM arguments for containerized app
     */
    List<String> jvmArguments;
    
    /**
     * Additional arguments for native app
     */
    List<String> arguments;
    
    /**
     * Working directory in container
     */
    @WithDefault("/work/")
    String workingDirectory;
    
    /**
     * User to run as in container
     */
    @WithDefault("1001")
    String user;
    
    /**
     * Exposed ports
     */
    List<Integer> ports;
    
    /**
     * Environment variables
     */
    Map<String, String> env;
    
    /**
     * Labels to add to container
     */
    Map<String, String> labels;
}

Usage Example:

@BuildStep(onlyIf = ContainerImageRequested.class)
void buildContainerImage(JarBuildItem jar,
                        Optional<NativeImageBuildItem> nativeImage,
                        ImageConfig imageConfig,
                        BuildProducer<ContainerImageBuildItem> containerImage) {
    
    ContainerImageBuilder builder = new ContainerImageBuilder();
    
    if (nativeImage.isPresent()) {
        // Native container image
        builder.from(imageConfig.baseNativeImage)
               .copy(nativeImage.get().getPath(), "/application")
               .workdir(imageConfig.workingDirectory)
               .user(imageConfig.user)
               .expose(imageConfig.ports)
               .env(imageConfig.env)
               .labels(imageConfig.labels)
               .cmd("/application");
    } else {
        // JVM container image
        builder.from(imageConfig.baseJvmImage)
               .copy(jar.getPath(), "/deployments/app.jar");
        
        if (jar.getLibraryDir().isPresent()) {
            builder.copy(jar.getLibraryDir().get(), "/deployments/lib/");
        }
        
        builder.workdir(imageConfig.workingDirectory)
               .user(imageConfig.user)
               .expose(imageConfig.ports)
               .env(imageConfig.env)
               .labels(imageConfig.labels)
               .cmd("java", "-jar", "/deployments/app.jar");
    }
    
    Path imagePath = builder.build();
    containerImage.produce(new ContainerImageBuildItem(imagePath));
}

AppCDS Support

AppCDS Configuration

Application Class Data Sharing for faster JVM startup.

class AppcdsConfig {
    /**
     * Whether AppCDS is enabled
     */
    @WithDefault("true")
    boolean enabled;
    
    /**
     * Additional JVM arguments for AppCDS generation
     */
    List<String> builderJvmArgs;
    
    /**
     * Whether to use container for AppCDS generation
     */
    @WithDefault("false")
    boolean useContainer;
}

class AppCDSBuildItem extends SimpleBuildItem {
    /**
     * Path to generated AppCDS archive
     */
    Path getAppCDSPath();
    
    /**
     * JVM arguments to use AppCDS archive
     */
    List<String> getAppCDSJvmArgs();
}

Usage Example:

@BuildStep(onlyIf = { JvmPackaging.class, AppCDSEnabled.class })
AppCDSBuildItem generateAppCDS(JarBuildItem jar,
                              AppcdsConfig appcdsConfig,
                              MainClassBuildItem mainClass) throws IOException {
    
    Path appCDSPath = jar.getPath().getParent().resolve("app.jsa");
    
    List<String> args = new ArrayList<>();
    args.add("-Xshare:dump");
    args.add("-XX:SharedArchiveFile=" + appCDSPath);
    args.add("-cp");
    args.add(buildClassPath(jar));
    args.addAll(appcdsConfig.builderJvmArgs);
    args.add(mainClass.getClassName());
    
    // Generate AppCDS archive
    executeJava(args);
    
    List<String> jvmArgs = List.of(
        "-Xshare:on",
        "-XX:SharedArchiveFile=" + appCDSPath
    );
    
    return new AppCDSBuildItem(appCDSPath, jvmArgs);
}

Software Bill of Materials (SBOM)

SBOM Configuration and Generation

class SbomConfig {
    /**
     * Whether to generate SBOM
     */
    @WithDefault("false")
    boolean enabled;
    
    /**
     * SBOM format (spdx, cyclonedx)
     */
    @WithDefault("spdx")
    SbomFormat format;
    
    /**
     * Include test dependencies
     */
    @WithDefault("false")  
    boolean includeTestDependencies;
    
    enum SbomFormat {
        SPDX, CYCLONEDX
    }
}

Usage Example:

@BuildStep(onlyIf = SbomEnabled.class)
void generateSbom(ApplicationArchivesBuildItem archives,
                 SbomConfig sbomConfig,
                 BuildProducer<GeneratedResourceBuildItem> resources) throws IOException {
    
    SbomGenerator generator = SbomGenerator.create(sbomConfig.format);
    
    // Add application information
    generator.addComponent("application", 
                          archives.getRootArchive().getKey().toString(),
                          "1.0.0");
    
    // Add dependencies
    for (ApplicationArchive archive : archives.getApplicationArchives()) {
        ResolvedDependency dep = archive.getResolvedDependency();
        generator.addDependency(
            dep.getGroupId() + ":" + dep.getArtifactId(),
            dep.getVersion(),
            "library"
        );
    }
    
    // Generate SBOM file
    String sbomContent = generator.generate();
    String filename = "sbom." + sbomConfig.format.name().toLowerCase();
    
    resources.produce(new GeneratedResourceBuildItem(
        "META-INF/" + filename, 
        sbomContent.getBytes(StandardCharsets.UTF_8)
    ));
}

Install with Tessl CLI

npx tessl i tessl/maven-io--quarkus--quarkus-core-deployment

docs

build-system.md

configuration.md

dev-mode.md

index.md

packaging.md

utilities.md

tile.json