diff --git a/bom/runtime/pom.xml b/bom/runtime/pom.xml
index 118f2211057042..4d6d468c15f1bb 100644
--- a/bom/runtime/pom.xml
+++ b/bom/runtime/pom.xml
@@ -31,7 +31,7 @@
1.3.1
1.0
1.3.4
- 1.3.9
+ 1.4.0
2.1.0
2.3.0
1.1.19
@@ -1067,6 +1067,11 @@
+
+ io.smallrye
+ smallrye-config-common
+ ${smallrye-config.version}
+
io.smallrye
smallrye-health
diff --git a/core/creator/src/main/java/io/quarkus/creator/phase/augment/AugmentTask.java b/core/creator/src/main/java/io/quarkus/creator/phase/augment/AugmentTask.java
index 2da772eaae17ae..bc238ed19f3b80 100644
--- a/core/creator/src/main/java/io/quarkus/creator/phase/augment/AugmentTask.java
+++ b/core/creator/src/main/java/io/quarkus/creator/phase/augment/AugmentTask.java
@@ -15,7 +15,9 @@
import java.util.Properties;
import java.util.function.Consumer;
+import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.spi.ConfigBuilder;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.jboss.logging.Logger;
import io.quarkus.bootstrap.BootstrapDependencyProcessingException;
@@ -36,7 +38,10 @@
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.builditem.JarBuildItem;
import io.quarkus.deployment.pkg.builditem.NativeImageBuildItem;
+import io.quarkus.runtime.configuration.QuarkusConfigFactory;
import io.smallrye.config.PropertiesConfigSource;
+import io.smallrye.config.SmallRyeConfig;
+import io.smallrye.config.SmallRyeConfigBuilder;
import io.smallrye.config.SmallRyeConfigProviderResolver;
/**
@@ -110,20 +115,26 @@ public AugmentOutcome run(CurateOutcome appState, CuratedApplicationCreator ctx)
}
//first lets look for some config, as it is not on the current class path
//and we need to load it to run the build process
- Path config = configDir.resolve("application.properties");
- if (Files.exists(config)) {
+ Path configPath = configDir.resolve("application.properties");
+ if (Files.exists(configPath)) {
try {
- ConfigBuilder builder = SmallRyeConfigProviderResolver.instance().getBuilder()
+ SmallRyeConfigBuilder builder = new SmallRyeConfigBuilder()
.addDefaultSources()
.addDiscoveredConverters()
.addDiscoveredSources()
- .withSources(new PropertiesConfigSource(config.toUri().toURL()));
+ .withSources(new PropertiesConfigSource(configPath.toUri().toURL()));
if (configCustomizer != null) {
configCustomizer.accept(builder);
}
- SmallRyeConfigProviderResolver.instance().registerConfig(builder.build(),
- Thread.currentThread().getContextClassLoader());
+ final SmallRyeConfig config = builder.build();
+ QuarkusConfigFactory.setConfig(config);
+ final ConfigProviderResolver cpr = ConfigProviderResolver.instance();
+ final Config existing = cpr.getConfig();
+ if (existing != config) {
+ cpr.releaseConfig(existing);
+ // subsequent calls will get the new config
+ }
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationConfig.java
index 180ae5ad3a1135..e430259613cdca 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/ApplicationConfig.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/ApplicationConfig.java
@@ -1,5 +1,7 @@
package io.quarkus.deployment;
+import java.util.Optional;
+
import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
@@ -12,12 +14,12 @@ public class ApplicationConfig {
* If not set, defaults to the name of the project.
*/
@ConfigItem
- public String name;
+ public Optional name;
/**
* The version of the application.
* If not set, defaults to the version of the project
*/
@ConfigItem
- public String version;
+ public Optional version;
}
diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java
index 2ccecac799b296..6ea739b2192252 100644
--- a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java
+++ b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java
@@ -25,12 +25,11 @@
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
-import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@@ -40,6 +39,7 @@
import java.util.function.Supplier;
import org.eclipse.microprofile.config.spi.ConfigBuilder;
+import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
import org.jboss.logging.Logger;
import org.wildfly.common.function.Functions;
@@ -62,33 +62,34 @@
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.annotations.Weak;
import io.quarkus.deployment.builditem.AdditionalApplicationArchiveMarkerBuildItem;
-import io.quarkus.deployment.builditem.BuildTimeConfigurationBuildItem;
-import io.quarkus.deployment.builditem.BuildTimeRunTimeFixedConfigurationBuildItem;
+import io.quarkus.deployment.builditem.BytecodeRecorderObjectLoaderBuildItem;
import io.quarkus.deployment.builditem.CapabilityBuildItem;
+import io.quarkus.deployment.builditem.ConfigurationBuildItem;
import io.quarkus.deployment.builditem.DeploymentClassLoaderBuildItem;
import io.quarkus.deployment.builditem.MainBytecodeRecorderBuildItem;
-import io.quarkus.deployment.builditem.RunTimeConfigurationBuildItem;
+import io.quarkus.deployment.builditem.RunTimeConfigurationProxyBuildItem;
import io.quarkus.deployment.builditem.StaticBytecodeRecorderBuildItem;
-import io.quarkus.deployment.builditem.UnmatchedConfigBuildItem;
-import io.quarkus.deployment.configuration.ConfigDefinition;
+import io.quarkus.deployment.configuration.BuildTimeConfigurationReader;
import io.quarkus.deployment.configuration.DefaultValuesConfigurationSource;
+import io.quarkus.deployment.configuration.definition.RootDefinition;
import io.quarkus.deployment.recording.BytecodeRecorderImpl;
+import io.quarkus.deployment.recording.ObjectLoader;
import io.quarkus.deployment.recording.RecorderContext;
import io.quarkus.deployment.util.ReflectUtil;
import io.quarkus.deployment.util.ServiceUtil;
+import io.quarkus.gizmo.BytecodeCreator;
import io.quarkus.gizmo.FieldDescriptor;
+import io.quarkus.gizmo.ResultHandle;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.quarkus.runtime.annotations.Recorder;
-import io.quarkus.runtime.configuration.ApplicationPropertiesConfigSource;
+import io.quarkus.runtime.configuration.ConfigUtils;
import io.quarkus.runtime.configuration.ConverterSupport;
-import io.quarkus.runtime.configuration.DeploymentProfileConfigSource;
-import io.quarkus.runtime.configuration.ExpandingConfigSource;
+import io.quarkus.runtime.configuration.QuarkusConfigFactory;
import io.smallrye.config.PropertiesConfigSource;
import io.smallrye.config.SmallRyeConfig;
import io.smallrye.config.SmallRyeConfigBuilder;
-import io.smallrye.config.SmallRyeConfigProviderResolver;
/**
* Utility class to load build steps, runtime recorders, and configuration roots from a given extension class.
@@ -104,11 +105,6 @@ private ExtensionLoader() {
public static final String RUN_TIME_CONFIG = "io.quarkus.runtime.generated.RunTimeConfig";
public static final String RUN_TIME_CONFIG_ROOT = "io.quarkus.runtime.generated.RunTimeConfigRoot";
- private static final FieldDescriptor RUN_TIME_CONFIG_FIELD = FieldDescriptor.of(RUN_TIME_CONFIG, "runConfig",
- RUN_TIME_CONFIG_ROOT);
- private static final FieldDescriptor BUILD_TIME_CONFIG_FIELD = FieldDescriptor.of(BUILD_TIME_CONFIG, "buildConfig",
- BUILD_TIME_CONFIG_ROOT);
-
private static final String CONFIG_ROOTS_LIST = "META-INF/quarkus-config-roots.list";
@SuppressWarnings("deprecation")
@@ -171,44 +167,29 @@ public static Consumer loadStepsFrom(ClassLoader classLoader,
LaunchMode launchMode, Consumer configCustomizer)
throws IOException, ClassNotFoundException {
- // set up the configuration definitions
- final ConfigDefinition buildTimeConfig = new ConfigDefinition(FieldDescriptor.of("Bogus", "No field", "Nothing"));
- final ConfigDefinition buildTimeRunTimeConfig = new ConfigDefinition(BUILD_TIME_CONFIG_FIELD);
- final ConfigDefinition runTimeConfig = new ConfigDefinition(RUN_TIME_CONFIG_FIELD, true);
-
- // populate it with all known types
+ // populate with all known types
+ List> roots = new ArrayList<>();
for (Class> clazz : ServiceUtil.classesNamedIn(classLoader, CONFIG_ROOTS_LIST)) {
final ConfigRoot annotation = clazz.getAnnotation(ConfigRoot.class);
if (annotation == null) {
cfgLog.warnf("Ignoring configuration root %s because it has no annotation", clazz);
} else {
- final ConfigPhase phase = annotation.phase();
- if (phase == ConfigPhase.RUN_TIME) {
- runTimeConfig.registerConfigRoot(clazz);
- } else if (phase == ConfigPhase.BUILD_AND_RUN_TIME_FIXED) {
- buildTimeRunTimeConfig.registerConfigRoot(clazz);
- } else if (phase == ConfigPhase.BUILD_TIME) {
- buildTimeConfig.registerConfigRoot(clazz);
- } else {
- cfgLog.warnf("Unrecognized configuration phase \"%s\" on %s", phase, clazz);
- }
+ roots.add(clazz);
}
}
+ final BuildTimeConfigurationReader reader = new BuildTimeConfigurationReader(roots);
+
// now prepare & load the build configuration
- final SmallRyeConfigBuilder builder = new SmallRyeConfigBuilder();
-
- // expand properties
- final ExpandingConfigSource.Cache cache = new ExpandingConfigSource.Cache();
- builder.withWrapper(ExpandingConfigSource.wrapper(cache));
- builder.withWrapper(DeploymentProfileConfigSource.wrapper());
- builder.addDefaultSources();
- final ApplicationPropertiesConfigSource.InJar inJar = new ApplicationPropertiesConfigSource.InJar();
- final DefaultValuesConfigurationSource defaultSource = new DefaultValuesConfigurationSource(
- buildTimeConfig.getLeafPatterns());
+ final SmallRyeConfigBuilder builder = ConfigUtils.configBuilder();
+
+ final DefaultValuesConfigurationSource ds1 = new DefaultValuesConfigurationSource(
+ reader.getBuildTimePatternMap());
+ final DefaultValuesConfigurationSource ds2 = new DefaultValuesConfigurationSource(
+ reader.getBuildTimeRunTimePatternMap());
final PropertiesConfigSource pcs = new PropertiesConfigSource(buildSystemProps, "Build system");
- builder.withSources(inJar, defaultSource, pcs);
+ builder.withSources(ds1, ds2, pcs);
// populate builder with all converters loaded from ServiceLoader
ConverterSupport.populateConverters(builder);
@@ -216,43 +197,53 @@ public static Consumer loadStepsFrom(ClassLoader classLoader,
if (configCustomizer != null) {
configCustomizer.accept(builder);
}
- final SmallRyeConfig src = (SmallRyeConfig) builder
- .addDefaultSources()
- .addDiscoveredSources()
- .addDiscoveredConverters()
- .build();
-
- SmallRyeConfigProviderResolver.instance().registerConfig(src, classLoader);
-
- Set unmatched = new HashSet<>();
-
- ConfigDefinition.loadConfiguration(cache, src,
- unmatched,
- buildTimeConfig,
- buildTimeRunTimeConfig, // this one is only for generating a default-values config source
- runTimeConfig);
+ final SmallRyeConfig src = builder.build();
+
+ // install globally
+ QuarkusConfigFactory.setConfig(src);
+ final ConfigProviderResolver cpr = ConfigProviderResolver.instance();
+ try {
+ cpr.releaseConfig(cpr.getConfig());
+ } catch (IllegalStateException ignored) {
+ // just means no config was installed, which is fine
+ }
- unmatched.removeIf(s -> !inJar.getPropertyNames().contains(s) && !s.startsWith("quarkus."));
+ final BuildTimeConfigurationReader.ReadResult readResult = reader.readConfiguration(src);
+ // the proxy objects used for run time config in the recorders
+ Map, Object> proxies = new HashMap<>();
Consumer result = Functions.discardingConsumer();
- result = result.andThen(bcb -> bcb.addBuildStep(bc -> {
- bc.produce(new BuildTimeConfigurationBuildItem(buildTimeConfig));
- bc.produce(new BuildTimeRunTimeFixedConfigurationBuildItem(buildTimeRunTimeConfig));
- bc.produce(new RunTimeConfigurationBuildItem(runTimeConfig));
- bc.produce(new UnmatchedConfigBuildItem(Collections.unmodifiableSet(unmatched)));
- }).produces(BuildTimeConfigurationBuildItem.class)
- .produces(BuildTimeRunTimeFixedConfigurationBuildItem.class)
- .produces(RunTimeConfigurationBuildItem.class)
- .produces(UnmatchedConfigBuildItem.class)
- .build());
for (Class> clazz : ServiceUtil.classesNamedIn(classLoader, "META-INF/quarkus-build-steps.list")) {
try {
- result = result
- .andThen(ExtensionLoader.loadStepsFrom(clazz, buildTimeConfig, buildTimeRunTimeConfig, launchMode));
+ result = result.andThen(
+ ExtensionLoader.loadStepsFrom(clazz, readResult, proxies, launchMode));
} catch (Throwable e) {
throw new RuntimeException("Failed to load steps from " + clazz, e);
}
}
+ // this has to be an identity hash map else the recorder will get angry
+ Map