diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index ed61f45ad8030..62d27e7483461 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -39,7 +39,7 @@
2.1.12
0.22.0
21.3
- 3.0.3
+ 3.1
4.0.1
4.0.1
1.3
diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigBuildStep.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigBuildStep.java
index bffd54d9b832c..8e9dce3d6591d 100644
--- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigBuildStep.java
+++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigBuildStep.java
@@ -2,6 +2,7 @@
import static io.quarkus.arc.processor.Annotations.getParameterAnnotations;
import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT;
+import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
import static io.quarkus.deployment.builditem.ConfigClassBuildItem.Kind.MAPPING;
import static io.quarkus.deployment.builditem.ConfigClassBuildItem.Kind.PROPERTIES;
import static io.quarkus.deployment.configuration.ConfigMappingUtils.CONFIG_MAPPING_NAME;
@@ -49,8 +50,10 @@
import io.quarkus.arc.processor.Annotations;
import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.arc.processor.BeanConfigurator;
+import io.quarkus.arc.processor.BuiltinScope;
import io.quarkus.arc.processor.DotNames;
import io.quarkus.arc.processor.InjectionPointInfo;
+import io.quarkus.arc.processor.ObserverInfo;
import io.quarkus.arc.runtime.ConfigBeanCreator;
import io.quarkus.arc.runtime.ConfigMappingCreator;
import io.quarkus.arc.runtime.ConfigRecorder;
@@ -135,8 +138,23 @@ void registerCustomConfigBeanTypes(BeanDiscoveryFinishedBuildItem beanDiscovery,
}
@BuildStep
- void validateConfigInjectionPoints(ValidationPhaseBuildItem validationPhase,
- BuildProducer configProperties) {
+ void configPropertyInjectionPoints(
+ ValidationPhaseBuildItem validationPhase,
+ BuildProducer configProperties,
+ BuildProducer reflectiveClass) {
+
+ // @Observes @Initialized(ApplicationScoped.class) requires validation at static init
+ Set observerMethods = new HashSet<>();
+ for (ObserverInfo observer : validationPhase.getBeanProcessor().getBeanDeployment().getObservers()) {
+ if (observer.isSynthetic()) {
+ continue;
+ }
+ AnnotationInstance instance = Annotations.getParameterAnnotation(observer.getObserverMethod(),
+ DotNames.INITIALIZED);
+ if (instance != null && instance.value().asClass().name().equals(BuiltinScope.APPLICATION.getName())) {
+ observerMethods.add(observer.getObserverMethod());
+ }
+ }
for (InjectionPointInfo injectionPoint : validationPhase.getContext().getInjectionPoints()) {
if (injectionPoint.hasDefaultedQualifier()) {
@@ -185,47 +203,43 @@ void validateConfigInjectionPoints(ValidationPhaseBuildItem validationPhase,
propertyDefaultValue = defaultValue.asString();
}
- configProperties.produce(new ConfigPropertyBuildItem(propertyName, injectedType, propertyDefaultValue));
+ if (injectionPoint.getTarget().kind().equals(METHOD)
+ && observerMethods.contains(injectionPoint.getTarget().asMethod())) {
+ configProperties
+ .produce(ConfigPropertyBuildItem.staticInit(propertyName, injectedType, propertyDefaultValue));
+ }
+
+ configProperties.produce(ConfigPropertyBuildItem.runtimeInit(propertyName, injectedType, propertyDefaultValue));
}
}
}
@BuildStep
- @Record(RUNTIME_INIT)
- void validateConfigValues(ConfigRecorder recorder, List configProperties,
- BeanContainerBuildItem beanContainer, BuildProducer reflectiveClass) {
- // IMPL NOTE: we do depend on BeanContainerBuildItem to make sure that the BeanDeploymentValidator finished its processing
-
- // the non-primitive types need to be registered for reflection since Class.forName is used at runtime to load the class
- for (ConfigPropertyBuildItem item : configProperties) {
- Type requiredType = item.getPropertyType();
- String propertyType = requiredType.name().toString();
- if (requiredType.kind() != Kind.PRIMITIVE) {
- reflectiveClass.produce(ReflectiveClassBuildItem.builder(propertyType).build());
- }
- }
+ @Record(STATIC_INIT)
+ void validateStaticInitConfigProperty(
+ ConfigRecorder recorder,
+ List configProperties,
+ BuildProducer reflectiveClass) {
- Set propertiesToValidate = new HashSet<>();
- for (ConfigPropertyBuildItem configProperty : configProperties) {
- String rawTypeName = configProperty.getPropertyType().name().toString();
- List actualTypeArgumentNames = Collections.emptyList();
- if (configProperty.getPropertyType().kind() == Kind.PARAMETERIZED_TYPE) {
- List argumentTypes = configProperty.getPropertyType().asParameterizedType().arguments();
- actualTypeArgumentNames = new ArrayList<>(argumentTypes.size());
- for (Type argumentType : argumentTypes) {
- actualTypeArgumentNames.add(argumentType.name().toString());
- if (argumentType.kind() != Kind.PRIMITIVE) {
- reflectiveClass.produce(ReflectiveClassBuildItem.builder(argumentType.name().toString())
- .build());
- }
- }
+ recorder.validateConfigProperties(
+ configProperties.stream()
+ .filter(ConfigPropertyBuildItem::isStaticInit)
+ .map(p -> configPropertyToConfigValidation(p, reflectiveClass))
+ .collect(toSet()));
+ }
- }
- propertiesToValidate.add(new ConfigValidationMetadata(configProperty.getPropertyName(),
- rawTypeName, actualTypeArgumentNames, configProperty.getDefaultValue()));
- }
+ @BuildStep
+ @Record(RUNTIME_INIT)
+ void validateRuntimeConfigProperty(
+ ConfigRecorder recorder,
+ List configProperties,
+ BuildProducer reflectiveClass) {
- recorder.validateConfigProperties(propertiesToValidate);
+ recorder.validateConfigProperties(
+ configProperties.stream()
+ .filter(ConfigPropertyBuildItem::isRuntimeInit)
+ .map(p -> configPropertyToConfigValidation(p, reflectiveClass))
+ .collect(toSet()));
}
@BuildStep
@@ -524,6 +538,30 @@ public static boolean isHandledByProducers(Type type) {
MP_CONFIG_VALUE_NAME.equals(type.name());
}
+ private static ConfigValidationMetadata configPropertyToConfigValidation(ConfigPropertyBuildItem configProperty,
+ BuildProducer reflectiveClass) {
+ String typeName = configProperty.getPropertyType().name().toString();
+ List typeArgumentNames = Collections.emptyList();
+
+ if (configProperty.getPropertyType().kind() != Kind.PRIMITIVE) {
+ reflectiveClass.produce(ReflectiveClassBuildItem.builder(typeName).build());
+ }
+
+ if (configProperty.getPropertyType().kind() == Kind.PARAMETERIZED_TYPE) {
+ List argumentTypes = configProperty.getPropertyType().asParameterizedType().arguments();
+ typeArgumentNames = new ArrayList<>(argumentTypes.size());
+ for (Type argumentType : argumentTypes) {
+ typeArgumentNames.add(argumentType.name().toString());
+ if (argumentType.kind() != Kind.PRIMITIVE) {
+ reflectiveClass.produce(ReflectiveClassBuildItem.builder(argumentType.name().toString()).build());
+ }
+ }
+ }
+
+ return new ConfigValidationMetadata(configProperty.getPropertyName(), typeName, typeArgumentNames,
+ configProperty.getDefaultValue());
+ }
+
private static Map configClassesToTypesMap(List configClasses,
ConfigClassBuildItem.Kind kind) {
Map configClassesTypes = new HashMap<>();
diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigPropertyBuildItem.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigPropertyBuildItem.java
index ad5fef88ab6cf..5e78261619882 100644
--- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigPropertyBuildItem.java
+++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/ConfigPropertyBuildItem.java
@@ -3,6 +3,7 @@
import org.jboss.jandex.Type;
import io.quarkus.builder.item.MultiBuildItem;
+import io.quarkus.runtime.ExecutionMode;
/**
* Represents a mandatory config property that needs to be validated at runtime.
@@ -11,11 +12,18 @@ public final class ConfigPropertyBuildItem extends MultiBuildItem {
private final String propertyName;
private final Type propertyType;
private final String defaultValue;
+ private final ExecutionMode executionMode;
+
+ private ConfigPropertyBuildItem(
+ final String propertyName,
+ final Type propertyType,
+ final String defaultValue,
+ final ExecutionMode executionMode) {
- public ConfigPropertyBuildItem(final String propertyName, final Type propertyType, final String defaultValue) {
this.propertyName = propertyName;
this.propertyType = propertyType;
this.defaultValue = defaultValue;
+ this.executionMode = executionMode;
}
public String getPropertyName() {
@@ -29,4 +37,30 @@ public Type getPropertyType() {
public String getDefaultValue() {
return defaultValue;
}
+
+ public ExecutionMode getExecutionMode() {
+ return executionMode;
+ }
+
+ public boolean isStaticInit() {
+ return executionMode.equals(ExecutionMode.STATIC_INIT);
+ }
+
+ public boolean isRuntimeInit() {
+ return executionMode.equals(ExecutionMode.RUNTIME_INIT);
+ }
+
+ public static ConfigPropertyBuildItem staticInit(
+ final String propertyName,
+ final Type propertyType,
+ final String defaultValue) {
+ return new ConfigPropertyBuildItem(propertyName, propertyType, defaultValue, ExecutionMode.STATIC_INIT);
+ }
+
+ public static ConfigPropertyBuildItem runtimeInit(
+ final String propertyName,
+ final Type propertyType,
+ final String defaultValue) {
+ return new ConfigPropertyBuildItem(propertyName, propertyType, defaultValue, ExecutionMode.RUNTIME_INIT);
+ }
}
diff --git a/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java b/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java
index a9082db669ce8..a8b14681e05b9 100644
--- a/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java
+++ b/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/ClassConfigurationPropertiesUtil.java
@@ -399,9 +399,8 @@ private ResultHandle populateConfigObject(ClassLoader classLoader, ClassInfo con
}
for (ConfigPropertyBuildItemCandidate candidate : configPropertyBuildItemCandidates) {
- configProperties
- .produce(new ConfigPropertyBuildItem(candidate.getConfigPropertyName(), candidate.getConfigPropertyType(),
- null));
+ configProperties.produce(ConfigPropertyBuildItem.runtimeInit(candidate.getConfigPropertyName(),
+ candidate.getConfigPropertyType(), null));
}
return configObject;
diff --git a/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/InterfaceConfigurationPropertiesUtil.java b/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/InterfaceConfigurationPropertiesUtil.java
index 7b642060b1cd9..a1dec9502c709 100644
--- a/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/InterfaceConfigurationPropertiesUtil.java
+++ b/extensions/spring-boot-properties/deployment/src/main/java/io/quarkus/spring/boot/properties/deployment/InterfaceConfigurationPropertiesUtil.java
@@ -259,8 +259,8 @@ private String generateImplementationForInterfaceConfigPropertiesRec(ClassInfo o
method.declaringClass().name(), methodCreator, config);
methodCreator.returnValue(value);
if (defaultValueStr == null || ConfigProperty.UNCONFIGURED_VALUE.equals(defaultValueStr)) {
- configProperties
- .produce(new ConfigPropertyBuildItem(fullConfigName, returnType, defaultValueStr));
+ configProperties.produce(
+ ConfigPropertyBuildItem.runtimeInit(fullConfigName, returnType, defaultValueStr));
}
}
}
diff --git a/tcks/microprofile-config/pom.xml b/tcks/microprofile-config/pom.xml
index f36b1ca04bfd5..2263e81879cb7 100644
--- a/tcks/microprofile-config/pom.xml
+++ b/tcks/microprofile-config/pom.xml
@@ -13,7 +13,7 @@
Quarkus - TCK - MicroProfile Config
- 3.0.3
+ 3.1
@@ -43,10 +43,6 @@
false
-
-
-
- false