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

utilities.mddocs/

Utilities

Quarkus Core Deployment provides a comprehensive set of utility classes for common deployment-time operations including reflection, file system operations, service loading, artifact handling, container runtime detection, and various helper functions that support the build and deployment process.

Core Imports

// Reflection utilities
import io.quarkus.deployment.util.ReflectUtil;
import io.quarkus.deployment.util.ClassUtil;
import io.quarkus.deployment.util.DeploymentUtil;

// Service loading utilities
import io.quarkus.deployment.util.ServiceUtil;

// File system utilities
import io.quarkus.deployment.util.FileUtil;
import io.quarkus.deployment.util.IoUtil;
import io.quarkus.deployment.util.PathUtil;

// Artifact and dependency utilities
import io.quarkus.deployment.util.ArtifactInfoUtil;
import io.quarkus.deployment.util.ArtifactResultBuilder;

// Container runtime utilities
import io.quarkus.deployment.util.ContainerRuntimeUtil;
import io.quarkus.deployment.util.ProcessUtil;

// Hashing and validation utilities
import io.quarkus.deployment.util.HashUtil;
import io.quarkus.deployment.util.StringUtil;

// Bean and proxy utilities
import io.quarkus.deployment.bean.BeanArchiveIndex;
import io.quarkus.deployment.bean.JavaBeanUtil;
import io.quarkus.deployment.proxy.ProxyFactory;

// Type parsing and handling
import io.quarkus.deployment.types.ParsedType;
import io.quarkus.deployment.types.TypeParser;

// Code generation framework
import io.quarkus.deployment.CodeGenProvider;
import io.quarkus.deployment.CodeGenContext;
import io.quarkus.deployment.CodeGenerator;
import io.quarkus.bootstrap.prebuild.CodeGenException;

Reflection Utilities

ReflectUtil

Comprehensive reflection utilities for deployment-time introspection and manipulation.

class ReflectUtil {
    /**
     * Gets a method by name and parameter types
     */
    static Method getMethod(Class<?> clazz, String name, Class<?>... parameterTypes)
        throws NoSuchMethodException;
    
    /**
     * Gets a field by name
     */
    static Field getField(Class<?> clazz, String name) 
        throws NoSuchFieldException;
    
    /**
     * Creates a new instance using default constructor
     */
    static <T> T newInstance(Class<T> clazz);
    
    /**
     * Creates a new instance using constructor with parameters
     */
    static <T> T newInstance(Class<T> clazz, Class<?>[] paramTypes, Object... args);
    
    /**
     * Invokes a method on an instance
     */
    static Object invoke(Method method, Object instance, Object... args);
    
    /**
     * Invokes a static method
     */
    static Object invokeStatic(Method method, Object... args);
    
    /**
     * Gets or sets a field value
     */
    static Object getFieldValue(Field field, Object instance);
    static void setFieldValue(Field field, Object instance, Object value);
    
    /**
     * Finds all methods with given annotation
     */
    static List<Method> getMethodsWithAnnotation(Class<?> clazz, 
                                               Class<? extends Annotation> annotation);
    
    /**
     * Finds all fields with given annotation
     */
    static List<Field> getFieldsWithAnnotation(Class<?> clazz,
                                              Class<? extends Annotation> annotation);
    
    /**
     * Gets raw class from parameterized type
     */
    static Class<?> getRawType(Type type);
    
    /**
     * Checks if class is assignable from type
     */
    static boolean isAssignableFrom(Class<?> clazz, Type type);
}

Usage Examples:

@BuildStep
void processReflectiveAccess(CombinedIndexBuildItem index,
                           BuildProducer<ReflectiveClassBuildItem> reflectiveClasses) {
    
    // Find all classes with @Entity annotation
    Collection<AnnotationInstance> entities = index.getIndex()
        .getAnnotations(DotName.createSimple("javax.persistence.Entity"));
    
    for (AnnotationInstance entity : entities) {
        String className = entity.target().asClass().name().toString();
        
        try {
            Class<?> entityClass = Class.forName(className);
            
            // Register class for reflection
            reflectiveClasses.produce(ReflectiveClassBuildItem.builder(entityClass)
                .constructors()
                .methods()
                .fields()
                .build());
            
            // Check for getter/setter methods
            List<Method> getters = ReflectUtil.getMethodsWithAnnotation(
                entityClass, Getter.class);
            List<Method> setters = ReflectUtil.getMethodsWithAnnotation(
                entityClass, Setter.class);
                
        } catch (ClassNotFoundException e) {
            // Handle missing class
        }
    }
}

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void setupReflection(MyRecorder recorder) {
    // Use reflection to configure framework
    recorder.configure(ReflectUtil.class);
}

Service Loading Utilities

ServiceUtil

Utilities for loading and managing service implementations via ServiceLoader.

class ServiceUtil {
    /**
     * Loads all implementations of a service from classpath
     */
    static <T> List<T> classPathServices(Class<T> serviceType, ClassLoader classLoader);
    
    /**
     * Loads first implementation of a service
     */
    static <T> Optional<T> classPathService(Class<T> serviceType, ClassLoader classLoader);
    
    /**
     * Loads services with specific context class loader
     */
    static <T> List<T> loadServices(Class<T> serviceType, ClassLoader classLoader);
    
    /**
     * Gets service implementation classes (not instances)
     */
    static <T> List<Class<? extends T>> loadServiceClasses(Class<T> serviceType, 
                                                          ClassLoader classLoader);
    
    /**
     * Checks if service implementation exists
     */
    static boolean hasService(Class<?> serviceType, ClassLoader classLoader);
    
    /**
     * Creates service loader for given type
     */
    static <T> ServiceLoader<T> load(Class<T> serviceType, ClassLoader classLoader);
}

Usage Examples:

@BuildStep
void discoverCompilationProviders(BuildProducer<CompilationProviderBuildItem> providers) {
    
    // Load all compilation providers from classpath
    List<CompilationProvider> compilationProviders = 
        ServiceUtil.classPathServices(CompilationProvider.class, 
                                     Thread.currentThread().getContextClassLoader());
    
    for (CompilationProvider provider : compilationProviders) {
        providers.produce(new CompilationProviderBuildItem(provider.getClass()));
    }
}

@BuildStep
void configureCodeGenerators(BuildProducer<CodeGenProviderBuildItem> codeGenProviders) {
    
    // Check if specific code generator is available
    if (ServiceUtil.hasService(GrpcCodeGenProvider.class, 
                              Thread.currentThread().getContextClassLoader())) {
        
        Optional<GrpcCodeGenProvider> provider = ServiceUtil.classPathService(
            GrpcCodeGenProvider.class,
            Thread.currentThread().getContextClassLoader());
            
        if (provider.isPresent()) {
            codeGenProviders.produce(new CodeGenProviderBuildItem(provider.get()));
        }
    }
}

File System Utilities

FileUtil

Comprehensive file system operations for deployment processing.

class FileUtil {
    /**
     * Copies a file from source to target
     */
    static void copyFile(Path source, Path target) throws IOException;
    
    /**
     * Copies directory recursively
     */
    static void copyDirectory(Path source, Path target) throws IOException;
    
    /**
     * Moves file or directory
     */
    static void moveFile(Path source, Path target) throws IOException;
    
    /**
     * Deletes file or directory recursively
     */
    static void deleteDirectory(Path directory) throws IOException;
    static boolean deleteIfExists(Path path) throws IOException;
    
    /**
     * Creates directories if they don't exist
     */
    static Path ensureDirectoryExists(Path directory) throws IOException;
    
    /**
     * Checks if directory is empty
     */
    static boolean isDirectoryEmpty(Path directory) throws IOException;
    
    /**
     * Gets relative path between two paths
     */
    static String relativize(Path base, Path child);
    
    /**
     * Reads file content as string
     */
    static String readFileToString(Path file, StandardCharsets charset) throws IOException;
    
    /**
     * Writes string content to file
     */
    static void writeStringToFile(Path file, String content, StandardCharsets charset) 
        throws IOException;
    
    /**
     * Lists files in directory with filter
     */
    static List<Path> listFiles(Path directory, String... extensions) throws IOException;
    
    /**
     * Finds files recursively with pattern
     */
    static List<Path> findFiles(Path directory, String pattern) throws IOException;
}

IoUtil

Lower-level I/O utilities and stream operations.

class IoUtil {
    /**
     * Reads all bytes from input stream
     */
    static byte[] readBytes(InputStream inputStream) throws IOException;
    
    /**
     * Copies input stream to output stream
     */
    static long copy(InputStream input, OutputStream output) throws IOException;
    
    /**
     * Reads properties from input stream
     */
    static Properties readProperties(InputStream inputStream) throws IOException;
    
    /**
     * Creates buffered reader for path
     */
    static BufferedReader newBufferedReader(Path path, Charset charset) throws IOException;
    
    /**
     * Creates buffered writer for path
     */
    static BufferedWriter newBufferedWriter(Path path, Charset charset) throws IOException;
    
    /**
     * Safely closes multiple closeables
     */
    static void safeClose(Closeable... closeables);
}

Usage Examples:

@BuildStep
void processConfigurationFiles(ApplicationArchivesBuildItem archives,
                              BuildProducer<ConfigurationBuildItem> config) throws IOException {
    
    for (ApplicationArchive archive : archives.getAllApplicationArchives()) {
        Path resourceDir = archive.apply(tree -> {
            OpenPathTree.PathVisit visit = tree.visit("META-INF");
            return visit != null ? visit.getPath() : null;
        });
        
        if (resourceDir != null) {
            // Find all .properties files
            List<Path> propFiles = FileUtil.findFiles(resourceDir, "*.properties");
            
            for (Path propFile : propFiles) {
                Properties props = new Properties();
                try (InputStream is = Files.newInputStream(propFile)) {
                    props = IoUtil.readProperties(is);
                }
                
                // Process properties
                processConfigProperties(props);
            }
        }
    }
}

@BuildStep
void generateConfigurationFiles(ConfigurationBuildItem config,
                               BuildProducer<GeneratedResourceBuildItem> resources) 
                               throws IOException {
    
    Path tempDir = Files.createTempDirectory("quarkus-config");
    try {
        // Generate configuration file
        Path configFile = tempDir.resolve("runtime-config.properties");
        
        Properties runtimeProps = new Properties();
        config.getPropertyNames().forEach(name -> {
            runtimeProps.setProperty(name, config.getValue(name, String.class).orElse(""));
        });
        
        try (OutputStream os = Files.newOutputStream(configFile)) {
            runtimeProps.store(os, "Generated runtime configuration");
        }
        
        // Read generated content
        byte[] content = FileUtil.readFileToString(configFile, StandardCharsets.UTF_8)
            .getBytes(StandardCharsets.UTF_8);
        
        resources.produce(new GeneratedResourceBuildItem(
            "META-INF/quarkus-runtime-config.properties", content));
        
    } finally {
        FileUtil.deleteDirectory(tempDir);
    }
}

Code Generation Framework

Quarkus provides a comprehensive code generation framework that allows extensions to generate source code during the build process. This system enables build-time code generation from various input formats including protobuf, OpenAPI, GraphQL schemas, and custom domain-specific languages.

CodeGenProvider

Interface for implementing custom code generators that run during the generate-sources phase.

interface CodeGenProvider {
    /**
     * Unique identifier for this code generator, corresponds to the directory 
     * name in generated-sources
     */
    String providerId();
    
    /**
     * File extensions that this code generator can process
     */
    String[] inputExtensions();
    
    /**
     * Name of the input directory relative to source roots
     * For example: src/main/{inputDirectory} and src/test/{inputDirectory}
     */
    String inputDirectory();
    
    /**
     * Optional absolute path override for input directory
     * Called after init(), returning null uses default inputDirectory()
     */
    default Path getInputDirectory() { return null; }
    
    /**
     * Initialize the provider with application model and build properties
     */
    default void init(ApplicationModel model, Map<String, String> properties) {}
    
    /**
     * Trigger code generation process
     * @param context Code generation context with paths and configuration
     * @return true if any files were generated or modified
     */
    boolean trigger(CodeGenContext context) throws CodeGenException;
    
    /**
     * Determine if code generator should run based on source directory and config
     */
    default boolean shouldRun(Path sourceDir, Config config) {
        return Files.isDirectory(sourceDir);
    }
}

CodeGenContext

Context object providing all necessary information for code generation.

class CodeGenContext {
    /**
     * Application model with dependency information
     */
    ApplicationModel applicationModel();
    
    /**
     * Target directory for generated output
     * Typically: target/generated-sources/{providerId}
     */
    Path outDir();
    
    /**
     * Working directory (typically project build directory)
     */
    Path workDir();
    
    /**
     * Input directory containing source files to process
     * Typically: src/main/{inputDirectory} or src/test/{inputDirectory}
     */
    Path inputDir();
    
    /**
     * Whether spawned processes should redirect I/O streams
     */
    boolean shouldRedirectIO();
    
    /**
     * Build-time configuration
     */
    Config config();
    
    /**
     * Whether generation is for tests (true) or main sources (false)
     */
    boolean test();
}

CodeGenerator

Static utility class for initializing and executing code generators.

class CodeGenerator {
    /**
     * Initialize and run all code generators for given parameters
     */
    static void initAndRun(
        QuarkusClassLoader classLoader,
        PathCollection sourceParentDirs,
        Path generatedSourcesDir,
        Path buildDir,
        Consumer<Path> sourceRegistrar,
        ApplicationModel appModel,
        Properties properties,
        String launchMode,
        boolean test
    ) throws CodeGenException;
    
    /**
     * Trigger a specific code generator
     */
    static boolean trigger(
        ClassLoader deploymentClassLoader,
        CodeGenData data,
        ApplicationModel appModel,
        Config config,
        boolean test
    ) throws CodeGenException;
    
    /**
     * Get build-time configuration for code generation
     */
    static Config getConfig(
        ApplicationModel appModel,
        LaunchMode launchMode,
        Properties buildSystemProps,
        QuarkusClassLoader deploymentClassLoader
    ) throws CodeGenException;
}

Usage Examples:

/**
 * Example: Protocol Buffer code generator
 */
public class ProtobufCodeGenProvider implements CodeGenProvider {
    
    @Override
    public String providerId() {
        return "protobuf";
    }
    
    @Override
    public String[] inputExtensions() {
        return new String[]{"proto"};
    }
    
    @Override
    public String inputDirectory() {
        return "proto";
    }
    
    @Override
    public void init(ApplicationModel model, Map<String, String> properties) {
        // Initialize protoc compiler path, output options, etc.
        this.protocPath = properties.get("protoc.path");
        this.javaOut = Boolean.parseBoolean(properties.get("protobuf.java.out"));
    }
    
    @Override  
    public boolean trigger(CodeGenContext context) throws CodeGenException {
        Path inputDir = context.inputDir();
        Path outputDir = context.outDir();
        
        if (!Files.exists(inputDir)) {
            return false;
        }
        
        boolean generated = false;
        try (Stream<Path> protoFiles = Files.walk(inputDir)) {
            List<Path> protoSources = protoFiles
                .filter(p -> p.toString().endsWith(".proto"))
                .collect(Collectors.toList());
                
            if (!protoSources.isEmpty()) {
                // Run protoc compiler
                List<String> command = List.of(
                    protocPath,
                    "--java_out=" + outputDir,
                    "--proto_path=" + inputDir
                );
                command.addAll(protoSources.stream()
                    .map(Path::toString)
                    .collect(Collectors.toList()));
                
                ProcessBuilder pb = new ProcessBuilder(command);
                if (context.shouldRedirectIO()) {
                    pb.inheritIO();
                }
                
                Process process = pb.start();
                int exitCode = process.waitFor();
                
                if (exitCode != 0) {
                    throw new CodeGenException("protoc compilation failed with exit code: " + exitCode);
                }
                
                generated = true;
            }
        } catch (IOException | InterruptedException e) {
            throw new CodeGenException("Protocol buffer code generation failed", e);
        }
        
        return generated;
    }
    
    @Override
    public boolean shouldRun(Path sourceDir, Config config) {
        return Files.isDirectory(sourceDir) && 
               config.getOptionalValue("quarkus.protobuf.enabled", Boolean.class).orElse(true);
    }
}

/**
 * Build step that configures code generation
 */
@BuildStep
void configureCodeGeneration(BuildProducer<CodeGenProviderBuildItem> codeGenProviders) {
    codeGenProviders.produce(new CodeGenProviderBuildItem(ProtobufCodeGenProvider.class.getName()));
}

/**
 * Integration with development mode
 */
@BuildStep
void setupDevModeCodeGeneration(LaunchModeBuildItem launchMode,
                               BuildProducer<HotDeploymentWatchedFileBuildItem> watchedFiles) {
    if (launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT) {
        // Watch .proto files for changes
        watchedFiles.produce(HotDeploymentWatchedFileBuildItem.builder()
            .setLocationGlob("src/main/proto/**/*.proto")
            .setRestartNeeded(true)
            .build());
    }
}

Artifact and Dependency Utilities

ArtifactInfoUtil

Utilities for working with Maven artifacts and dependency information.

class ArtifactInfoUtil {
    /**
     * Parses artifact coordinates from string
     */
    static ArtifactKey parseArtifactKey(String coords);
    
    /**
     * Creates artifact key from components
     */
    static ArtifactKey createArtifactKey(String groupId, String artifactId, 
                                        String classifier, String type);
    
    /**
     * Gets artifact version from dependency
     */
    static String getArtifactVersion(ResolvedDependency dependency);
    
    /**
     * Checks if artifact matches pattern
     */
    static boolean matches(ArtifactKey artifact, String pattern);
    
    /**
     * Gets all transitive dependencies
     */
    static Set<ResolvedDependency> getTransitiveDependencies(
        ResolvedDependency rootDependency,
        boolean includeOptional
    );
    
    /**
     * Filters dependencies by scope
     */
    static List<ResolvedDependency> filterByScope(
        List<ResolvedDependency> dependencies,
        String... scopes
    );
    
    /**
     * Creates dependency tree string representation
     */
    static String createDependencyTree(ApplicationModel applicationModel);
}

Usage Examples:

@BuildStep
void analyzeDependencies(ApplicationArchivesBuildItem archives,
                        BuildProducer<DependencyAnalysisBuildItem> analysis) {
    
    List<ResolvedDependency> runtimeDeps = new ArrayList<>();
    
    for (ApplicationArchive archive : archives.getApplicationArchives()) {
        ResolvedDependency dependency = archive.getResolvedDependency();
        
        if (dependency != null) {
            // Filter runtime dependencies
            if (ArtifactInfoUtil.filterByScope(List.of(dependency), "compile", "runtime")
                .contains(dependency)) {
                runtimeDeps.add(dependency);
            }
            
            // Check for specific artifacts
            if (ArtifactInfoUtil.matches(dependency.getKey(), "org.hibernate.*")) {
                // Handle Hibernate dependency
                handleHibernateDependency(dependency);
            }
        }
    }
    
    analysis.produce(new DependencyAnalysisBuildItem(runtimeDeps));
}

Container Runtime Utilities

ContainerRuntimeUtil

Utilities for detecting and working with container runtimes like Docker and Podman.

class ContainerRuntimeUtil {
    /**
     * Detects available container runtime
     */
    static Optional<ContainerRuntime> detectContainerRuntime();
    
    /**
     * Checks if container runtime is available
     */
    static boolean isContainerRuntimeAvailable();
    
    /**
     * Gets container runtime executable path
     */
    static Optional<String> getContainerRuntimeExecutable();
    
    /**
     * Executes container command
     */
    static ProcessResult executeContainerCommand(List<String> command, 
                                                Path workingDirectory) 
                                                throws IOException;
    
    /**
     * Builds container image
     */
    static ProcessResult buildImage(Path dockerfile, 
                                   String imageName,
                                   Path context) throws IOException;
    
    /**
     * Runs container
     */
    static ProcessResult runContainer(String imageName,
                                     Map<String, String> env,
                                     List<String> ports,
                                     List<String> volumes) throws IOException;
    
    enum ContainerRuntime {
        DOCKER("docker"),
        PODMAN("podman");
        
        String getExecutableName();
        List<String> getDefaultOptions();
    }
}

ProcessUtil

Utilities for executing external processes.

class ProcessUtil {
    /**
     * Executes process with arguments
     */
    static ProcessResult execute(List<String> command, 
                                Path workingDirectory,
                                Map<String, String> environment,
                                Duration timeout) throws IOException;
    
    /**
     * Executes process and returns result
     */
    static ProcessResult executeAndWait(String... command) throws IOException;
    
    /**
     * Checks if executable is available in PATH
     */
    static boolean isExecutableInPath(String executable);
    
    /**
     * Gets executable path
     */
    static Optional<Path> findExecutable(String executable);
    
    /**
     * Process execution result
     */
    static class ProcessResult {
        int getExitCode();
        String getStdout();
        String getStderr();
        boolean isSuccess();
        Duration getDuration();
    }
}

Usage Examples:

@BuildStep(onlyIf = ContainerImageRequested.class)
void buildContainerImage(JarBuildItem jar,
                        ImageConfig imageConfig,
                        BuildProducer<ContainerImageBuildItem> containerImage) 
                        throws IOException {
    
    if (!ContainerRuntimeUtil.isContainerRuntimeAvailable()) {
        throw new RuntimeException("No container runtime available for image building");
    }
    
    ContainerRuntime runtime = ContainerRuntimeUtil.detectContainerRuntime()
        .orElseThrow(() -> new RuntimeException("Container runtime detection failed"));
    
    // Generate Dockerfile
    Path dockerfile = generateDockerfile(jar, imageConfig);
    
    // Build image
    String imageName = "quarkus-app:latest";
    ProcessResult result = ContainerRuntimeUtil.buildImage(
        dockerfile, 
        imageName, 
        jar.getPath().getParent()
    );
    
    if (!result.isSuccess()) {
        throw new RuntimeException("Container image build failed: " + result.getStderr());
    }
    
    containerImage.produce(new ContainerImageBuildItem(imageName));
}

Hash and Validation Utilities

HashUtil

Utilities for generating hashes and checksums.

class HashUtil {
    /**
     * Generates SHA-256 hash of file
     */
    static String sha256(Path file) throws IOException;
    
    /**
     * Generates SHA-256 hash of bytes
     */
    static String sha256(byte[] data);
    
    /**
     * Generates MD5 hash of file
     */
    static String md5(Path file) throws IOException;
    
    /**
     * Generates hash using specified algorithm
     */
    static String hash(Path file, String algorithm) throws IOException;
    
    /**
     * Verifies file against checksum
     */
    static boolean verify(Path file, String expectedHash, String algorithm) throws IOException;
    
    /**
     * Generates hash of directory contents
     */
    static String directoryHash(Path directory, String algorithm) throws IOException;
}

StringUtil

String manipulation and validation utilities.

class StringUtil {
    /**
     * Converts string to kebab-case
     */
    static String toKebabCase(String input);
    
    /**
     * Converts string to camelCase
     */
    static String toCamelCase(String input);
    
    /**
     * Converts string to PascalCase
     */
    static String toPascalCase(String input);
    
    /**
     * Checks if string is null or empty
     */
    static boolean isNullOrEmpty(String str);
    
    /**
     * Checks if string is null, empty, or whitespace
     */
    static boolean isNullOrBlank(String str);
    
    /**
     * Joins strings with delimiter
     */
    static String join(String delimiter, String... parts);
    static String join(String delimiter, Collection<String> parts);
    
    /**
     * Splits string and trims whitespace
     */
    static List<String> splitAndTrim(String input, String delimiter);
    
    /**
     * Replaces placeholders in template
     */
    static String substitute(String template, Map<String, String> replacements);
}

Usage Examples:

@BuildStep
void generateHashManifest(JarBuildItem jar,
                         BuildProducer<GeneratedResourceBuildItem> resources) throws IOException {
    
    // Generate hash of JAR file
    String jarHash = HashUtil.sha256(jar.getPath());
    
    // Generate hash of dependencies
    Map<String, String> dependencyHashes = new HashMap<>();
    if (jar.getLibraryDir().isPresent()) {
        List<Path> libFiles = FileUtil.listFiles(jar.getLibraryDir().get(), "jar");
        for (Path libFile : libFiles) {
            String hash = HashUtil.sha256(libFile);
            dependencyHashes.put(libFile.getFileName().toString(), hash);
        }
    }
    
    // Create manifest content
    StringBuilder manifest = new StringBuilder();
    manifest.append("application.jar=").append(jarHash).append("\n");
    dependencyHashes.forEach((name, hash) -> 
        manifest.append("lib/").append(name).append("=").append(hash).append("\n"));
    
    resources.produce(new GeneratedResourceBuildItem(
        "META-INF/quarkus-hash-manifest.txt",
        manifest.toString().getBytes(StandardCharsets.UTF_8)
    ));
}

@BuildStep
void processConfigurationKeys(ConfigurationBuildItem config,
                             BuildProducer<ConfigKeyBuildItem> configKeys) {
    
    // Convert configuration keys to different naming conventions
    for (String propertyName : config.getPropertyNames()) {
        String kebabCase = StringUtil.toKebabCase(propertyName);
        String camelCase = StringUtil.toCamelCase(propertyName);
        
        configKeys.produce(new ConfigKeyBuildItem(propertyName, kebabCase, camelCase));
    }
}

Bean and Proxy Utilities

JavaBeanUtil

Utilities for working with JavaBeans and property introspection.

class JavaBeanUtil {
    /**
     * Gets bean properties for class
     */
    static List<PropertyDescriptor> getBeanProperties(Class<?> beanClass);
    
    /**
     * Checks if method is a getter
     */
    static boolean isGetter(Method method);
    
    /**
     * Checks if method is a setter
     */
    static boolean isSetter(Method method);
    
    /**
     * Gets property name from getter/setter method
     */
    static String getPropertyName(Method method);
    
    /**
     * Gets property type
     */
    static Class<?> getPropertyType(PropertyDescriptor property);
    
    /**
     * Sets property value using setter
     */
    static void setProperty(Object bean, String propertyName, Object value);
    
    /**
     * Gets property value using getter
     */
    static Object getProperty(Object bean, String propertyName);
}

ProxyFactory

Factory for creating runtime proxies for interfaces.

class ProxyFactory {
    /**
     * Creates proxy for interface with invocation handler
     */
    static <T> T createProxy(Class<T> interfaceType, 
                            InvocationHandler handler,
                            ClassLoader classLoader);
    
    /**
     * Creates proxy class for interface
     */
    static Class<?> createProxyClass(Class<?>[] interfaces, 
                                    ClassLoader classLoader);
    
    /**
     * Checks if class is a proxy class
     */
    static boolean isProxyClass(Class<?> clazz);
}

Usage Examples:

@BuildStep
void processConfigurationBeans(CombinedIndexBuildItem index,
                              BuildProducer<ConfigBeanBuildItem> configBeans) {
    
    // Find classes annotated with @ConfigProperties
    Collection<AnnotationInstance> configProperties = index.getIndex()
        .getAnnotations(DotName.createSimple("io.quarkus.arc.config.ConfigProperties"));
    
    for (AnnotationInstance annotation : configProperties) {
        String className = annotation.target().asClass().name().toString();
        
        try {
            Class<?> configClass = Class.forName(className);
            
            // Get bean properties
            List<PropertyDescriptor> properties = JavaBeanUtil.getBeanProperties(configClass);
            
            for (PropertyDescriptor property : properties) {
                String configKey = StringUtil.toKebabCase(property.getName());
                configBeans.produce(new ConfigBeanBuildItem(
                    configClass, 
                    property.getName(),
                    configKey,
                    property.getPropertyType()
                ));
            }
            
        } catch (ClassNotFoundException e) {
            // Handle missing class
        }
    }
}

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