Core deployment-time APIs and infrastructure for building Quarkus applications with native image support and development-time features
—
Quarkus provides a comprehensive configuration system that handles both build-time and runtime configuration with type-safe binding, validation, and environment-specific overrides. The configuration system supports multiple sources including properties files, environment variables, system properties, and programmatic configuration.
// Configuration readers and generators
import io.quarkus.deployment.configuration.BuildTimeConfigurationReader;
import io.quarkus.deployment.configuration.RunTimeConfigurationGenerator;
import io.quarkus.deployment.configuration.ClassLoadingConfig;
// Configuration build items
import io.quarkus.deployment.builditem.ConfigurationBuildItem;
import io.quarkus.deployment.builditem.StaticInitConfigSourceProviderBuildItem;
import io.quarkus.deployment.builditem.RunTimeConfigurationDefaultBuildItem;
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
// Configuration definition types
import io.quarkus.deployment.configuration.definition.RootDefinition;
import io.quarkus.deployment.configuration.definition.ClassDefinition;
import io.quarkus.deployment.configuration.definition.GroupDefinition;
// Configuration mapping and tracking
import io.quarkus.deployment.configuration.matching.ConfigPatternMap;
import io.quarkus.deployment.configuration.tracker.ConfigTrackingWriter;
// Runtime configuration types
import io.quarkus.runtime.configuration.ConfigBuilder;
import io.quarkus.runtime.configuration.ConfigurationException;
// SmallRye Config integration
import io.smallrye.config.Config;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.ConfigMappingContext;
import io.smallrye.config.WithDefault;
import io.smallrye.config.WithName;Reads and processes build-time configuration from various sources.
class BuildTimeConfigurationReader {
/**
* Reads build-time configuration from application sources
*/
static RunTimeConfigurationGenerator.ReadResult readConfiguration(
Path applicationRoot,
Path outputDirectory,
ConfigMappingContext configMappingContext,
LaunchMode launchMode
);
/**
* Reads configuration with custom sources and converters
*/
static RunTimeConfigurationGenerator.ReadResult readConfiguration(
Path applicationRoot,
Path outputDirectory,
ConfigMappingContext configMappingContext,
LaunchMode launchMode,
List<ConfigSourceProvider> configSourceProviders,
List<Converter<?>> converters
);
}Generates runtime configuration setup code.
class RunTimeConfigurationGenerator {
/**
* Generated configuration class name
*/
static final String CONFIG_CLASS_NAME = "io.quarkus.runtime.generated.Config";
static final String CONFIG_STATIC_NAME = "io.quarkus.runtime.generated.StaticInitConfig";
static final String CONFIG_RUNTIME_NAME = "io.quarkus.runtime.generated.RunTimeConfig";
/**
* Method descriptors for generated configuration methods
*/
static final MethodDescriptor C_CREATE_RUN_TIME_CONFIG;
static final MethodDescriptor C_ENSURE_INITIALIZED;
static final MethodDescriptor REINIT;
static final MethodDescriptor C_READ_CONFIG;
/**
* Main configuration generation operation builder
*/
static final class GenerateOperation implements AutoCloseable {
/**
* Creates a new generation operation builder
*/
static Builder builder();
@Override
void close();
static final class Builder {
/**
* Sets whether live reload is possible
*/
Builder setLiveReloadPossible(boolean liveReloadPossible);
/**
* Sets the launch mode for configuration
*/
Builder setLaunchMode(LaunchMode launchMode);
/**
* Sets the class output for generated classes
*/
Builder setClassOutput(ClassOutput classOutput);
/**
* Sets the build-time configuration read result
*/
Builder setBuildTimeReadResult(BuildTimeConfigurationReader.ReadResult result);
/**
* Sets additional types for configuration mapping
*/
Builder setAdditionalTypes(List<Class<?>> additionalTypes);
/**
* Builds the generation operation
*/
GenerateOperation build();
}
}
}Usage Example:
@BuildStep
void generateConfiguration(ApplicationArchivesBuildItem archives,
BuildProducer<GeneratedClassBuildItem> generatedClasses,
LaunchModeBuildItem launchMode,
List<ConfigClassBuildItem> configClasses) throws Exception {
// Read build-time configuration
BuildTimeConfigurationReader configReader = new BuildTimeConfigurationReader(deploymentClassLoader);
BuildTimeConfigurationReader.ReadResult readResult =
configReader.readConfiguration(launchMode.getLaunchMode());
// Set up class output for generated configuration classes
ClassOutput classOutput = new ClassOutput() {
@Override
public void writeClass(boolean applicationClass, String className, byte[] data) {
generatedClasses.produce(new GeneratedClassBuildItem(applicationClass, className, data));
}
};
// Generate runtime configuration using builder pattern
List<Class<?>> additionalTypes = configClasses.stream()
.map(ConfigClassBuildItem::getConfigClass)
.collect(Collectors.toList());
try (RunTimeConfigurationGenerator.GenerateOperation operation =
RunTimeConfigurationGenerator.GenerateOperation.builder()
.setLaunchMode(launchMode.getLaunchMode())
.setLiveReloadPossible(launchMode.getLaunchMode() == LaunchMode.DEVELOPMENT)
.setClassOutput(classOutput)
.setBuildTimeReadResult(readResult)
.setAdditionalTypes(additionalTypes)
.build()) {
// The GenerateOperation automatically generates the configuration classes
// when built and properly closed via try-with-resources
}
}Contains build-time configuration information.
class ConfigurationBuildItem extends SimpleBuildItem {
/**
* Gets the build-time configuration instance
*/
Config getConfig();
/**
* Gets configuration property names
*/
Set<String> getPropertyNames();
/**
* Checks if a property is present
*/
boolean hasProperty(String propertyName);
/**
* Gets a configuration value with type conversion
*/
<T> Optional<T> getValue(String propertyName, Class<T> type);
}Represents system properties to be set at runtime.
class SystemPropertyBuildItem extends MultiBuildItem {
/**
* Creates a system property build item
*/
SystemPropertyBuildItem(String key, String value);
String getKey();
String getValue();
}class StaticInitConfigSourceProviderBuildItem extends MultiBuildItem {
/**
* Creates a config source provider for static initialization
*/
StaticInitConfigSourceProviderBuildItem(String configSourceProviderClassName);
String getConfigSourceProviderClassName();
}
class RunTimeConfigurationDefaultBuildItem extends MultiBuildItem {
/**
* Sets a default value for runtime configuration
*/
RunTimeConfigurationDefaultBuildItem(String key, String value);
String getKey();
String getValue();
}Usage Examples:
@BuildStep
void setupSystemProperties(BuildProducer<SystemPropertyBuildItem> systemProps) {
systemProps.produce(new SystemPropertyBuildItem("quarkus.application.name", "my-app"));
systemProps.produce(new SystemPropertyBuildItem("java.util.logging.manager",
"org.jboss.logmanager.LogManager"));
}
@BuildStep
void addConfigSource(BuildProducer<StaticInitConfigSourceProviderBuildItem> configSources) {
configSources.produce(new StaticInitConfigSourceProviderBuildItem(
"com.example.MyConfigSourceProvider"));
}
@BuildStep
void addRuntimeDefaults(BuildProducer<RunTimeConfigurationDefaultBuildItem> defaults) {
defaults.produce(new RunTimeConfigurationDefaultBuildItem("app.timeout", "30s"));
defaults.produce(new RunTimeConfigurationDefaultBuildItem("app.retries", "3"));
}Defines a configuration root for type-safe configuration binding.
class RootDefinition extends GroupDefinition {
/**
* Creates a configuration root definition
*/
static RootDefinition builder(String name, Class<?> configClass)
.withDefaults()
.withConverter(Class<? extends Converter<?>> converterClass)
.withValidator(Class<? extends Validator<?>> validatorClass)
.build();
String getName();
Class<?> getConfigurationClass();
}class ClassDefinition {
String getClassName();
Map<String, Object> getDefaults();
List<MethodDefinition> getMethods();
List<FieldDefinition> getFields();
}
class GroupDefinition extends ClassDefinition {
/**
* Nested configuration groups
*/
Map<String, GroupDefinition> getGroups();
/**
* Configuration properties in this group
*/
Map<String, PropertyDefinition> getProperties();
}Usage Example:
// Configuration class
@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public class DatabaseConfig {
/**
* Database URL
*/
@WithDefault("jdbc:h2:mem:test")
public String url;
/**
* Database driver class
*/
@WithDefault("org.h2.Driver")
public String driver;
/**
* Connection pool configuration
*/
public PoolConfig pool;
@ConfigGroup
public static class PoolConfig {
@WithDefault("10")
public int maxSize;
@WithDefault("5")
public int minSize;
}
}
// Build step using configuration
@BuildStep
void processDatabaseConfig(DatabaseConfig config,
BuildProducer<DataSourceBuildItem> dataSources) {
dataSources.produce(new DataSourceBuildItem(config.url, config.driver));
}Type-safe configuration binding using interfaces.
@ConfigMapping(prefix = "app.database")
interface DatabaseConfiguration {
/**
* Database URL with default value
*/
@WithDefault("jdbc:h2:mem:test")
String url();
/**
* Database driver with custom property name
*/
@WithName("driver-class")
@WithDefault("org.h2.Driver")
String driverClass();
/**
* Connection pool configuration group
*/
PoolConfiguration pool();
/**
* Optional SSL configuration
*/
Optional<SslConfiguration> ssl();
interface PoolConfiguration {
@WithDefault("10")
int maxSize();
@WithDefault("2")
int minSize();
@WithDefault("30s")
Duration timeout();
}
interface SslConfiguration {
boolean enabled();
String keystorePath();
String keystorePassword();
}
}Context for configuration mapping operations.
class ConfigMappingContext {
/**
* Registers a configuration mapping interface
*/
void registerConfigMapping(Class<?> configMappingClass);
/**
* Gets registered configuration mappings
*/
Set<Class<?>> getConfigMappings();
/**
* Creates a configuration mapping instance
*/
<T> T getConfigMapping(Class<T> mappingClass, Config config);
}Usage Example:
@BuildStep
void registerConfigMapping(BuildProducer<ConfigMappingBuildItem> mappings) {
mappings.produce(new ConfigMappingBuildItem(DatabaseConfiguration.class));
}
@BuildStep
void useConfigMapping(ConfigurationBuildItem configItem,
BuildProducer<DataSourceBuildItem> dataSources) {
Config config = configItem.getConfig();
DatabaseConfiguration dbConfig = config.getConfigMapping(DatabaseConfiguration.class);
dataSources.produce(new DataSourceBuildItem(
dbConfig.url(),
dbConfig.driverClass(),
dbConfig.pool().maxSize()
));
}Tracks configuration changes for hot reloading.
class ConfigTrackingWriter {
/**
* Writes configuration tracking information
*/
static void write(ConfigTrackingConfig config, Path outputPath);
/**
* Tracks configuration property access
*/
static void trackConfigProperty(String propertyName);
/**
* Gets tracked configuration properties
*/
static Set<String> getTrackedProperties();
}Maps configuration patterns to values for flexible configuration matching.
class ConfigPatternMap<T> {
/**
* Creates a new pattern map
*/
static <T> Builder<T> builder();
/**
* Matches a key against registered patterns
*/
List<T> findMatches(String key);
/**
* Gets exact match for a key
*/
Optional<T> getExactMatch(String key);
static class Builder<T> {
Builder<T> put(String pattern, T value);
Builder<T> putAll(Map<String, T> patterns);
ConfigPatternMap<T> build();
}
}Usage Example:
@BuildStep
void configurePatternMatching(ConfigurationBuildItem config,
BuildProducer<ConfigPatternBuildItem> patterns) {
ConfigPatternMap<String> datasourcePatterns = ConfigPatternMap.<String>builder()
.put("quarkus.datasource.*.url", "jdbc-url")
.put("quarkus.datasource.*.driver", "driver-class")
.put("quarkus.datasource.*.username", "user")
.put("quarkus.datasource.*.password", "pass")
.build();
patterns.produce(new ConfigPatternBuildItem("datasource", datasourcePatterns));
}@BuildStep
void registerConverters(BuildProducer<ConfigConverterBuildItem> converters) {
converters.produce(new ConfigConverterBuildItem(DurationConverter.class));
converters.produce(new ConfigConverterBuildItem(SizeConverter.class));
}
public class DurationConverter implements Converter<Duration> {
@Override
public Duration convert(String value) throws IllegalArgumentException {
if (value == null || value.trim().isEmpty()) {
return null;
}
return Duration.parse("PT" + value.toUpperCase());
}
}@BuildStep
void validateConfiguration(ConfigurationBuildItem config) {
Config c = config.getConfig();
// Validate required properties
List<String> requiredProps = Arrays.asList(
"quarkus.application.name",
"quarkus.http.port"
);
for (String prop : requiredProps) {
if (!c.getOptionalValue(prop, String.class).isPresent()) {
throw new ConfigurationException("Required property " + prop + " is missing");
}
}
// Validate value ranges
int httpPort = c.getValue("quarkus.http.port", Integer.class);
if (httpPort < 1 || httpPort > 65535) {
throw new ConfigurationException("HTTP port must be between 1 and 65535");
}
}@BuildStep
void setupProfileConfiguration(LaunchModeBuildItem launchMode,
BuildProducer<SystemPropertyBuildItem> systemProps) {
String profile = switch (launchMode.getLaunchMode()) {
case DEVELOPMENT -> "dev";
case TEST -> "test";
case NORMAL -> "prod";
};
systemProps.produce(new SystemPropertyBuildItem("quarkus.profile", profile));
}
// Configuration with profile-specific values
@BuildStep
void configureByProfile(ConfigurationBuildItem config,
LaunchModeBuildItem launchMode,
BuildProducer<DatabaseBuildItem> database) {
Config c = config.getConfig();
String profile = c.getOptionalValue("quarkus.profile", String.class).orElse("prod");
String dbUrl = switch (profile) {
case "dev" -> c.getOptionalValue("quarkus.datasource.dev.jdbc-url", String.class)
.orElse("jdbc:h2:mem:devdb");
case "test" -> c.getOptionalValue("quarkus.datasource.test.jdbc-url", String.class)
.orElse("jdbc:h2:mem:testdb");
default -> c.getValue("quarkus.datasource.jdbc-url", String.class);
};
database.produce(new DatabaseBuildItem(dbUrl));
}@BuildSteps
public class ConfigurationProcessor {
@BuildStep
ConfigurationBuildItem readConfiguration(ApplicationArchivesBuildItem archives,
LaunchModeBuildItem launchMode) {
// Read and process configuration from all sources
}
@BuildStep
void processSystemProperties(ConfigurationBuildItem config,
BuildProducer<SystemPropertyBuildItem> systemProps) {
// Convert config properties to system properties where needed
}
@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void setupStaticConfig(ConfigRecorder recorder,
List<StaticInitConfigSourceProviderBuildItem> configSources) {
List<String> providers = configSources.stream()
.map(StaticInitConfigSourceProviderBuildItem::getConfigSourceProviderClassName)
.collect(Collectors.toList());
recorder.registerStaticConfigSources(providers);
}
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void setupRuntimeConfig(ConfigRecorder recorder,
List<RunTimeConfigurationDefaultBuildItem> defaults,
ShutdownContextBuildItem shutdown) {
Map<String, String> defaultValues = defaults.stream()
.collect(Collectors.toMap(
RunTimeConfigurationDefaultBuildItem::getKey,
RunTimeConfigurationDefaultBuildItem::getValue
));
recorder.setupRuntimeConfig(defaultValues, shutdown);
}
}Install with Tessl CLI
npx tessl i tessl/maven-io--quarkus--quarkus-core-deployment