From b7524c0cce0afbe9183e6f523868bf6784d248e6 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 23 Aug 2021 09:03:46 +0300 Subject: [PATCH] Provide clear build-time error message when using Map in @ConfigProperties Fixes: #19366 --- .../ConfigPropertiesUtil.java | 15 +++++++ .../deployment/configproperties/DotNames.java | 4 ++ .../arc/test/configproperties/MapTest.java | 41 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 extensions/arc/deployment/src/test/java/io/quarkus/arc/test/configproperties/MapTest.java diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/ConfigPropertiesUtil.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/ConfigPropertiesUtil.java index 48de13b00794b..a6c78c961a25f 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/ConfigPropertiesUtil.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/ConfigPropertiesUtil.java @@ -4,6 +4,8 @@ import java.util.Optional; import java.util.function.IntFunction; +import javax.enterprise.inject.spi.DeploymentException; + import org.eclipse.microprofile.config.Config; import org.jboss.jandex.DotName; import org.jboss.jandex.ParameterizedType; @@ -42,6 +44,10 @@ static ResultHandle createReadMandatoryValueAndConvertIfNeeded(String propertyNa DotName declaringClass, BytecodeCreator bytecodeCreator, ResultHandle config) { + if (isMap(resultType)) { + throw new DeploymentException( + "Using a Map is not supported for classes annotated with '@ConfigProperties'. Consider using https://quarkus.io/guides/config-mappings instead."); + } if (isCollection(resultType)) { ResultHandle smallryeConfig = bytecodeCreator.checkCast(config, SmallRyeConfig.class); @@ -79,6 +85,10 @@ static ReadOptionalResponse createReadOptionalValueAndConvertIfNeeded(String pro BytecodeCreator bytecodeCreator, ResultHandle config) { ResultHandle optionalValue; + if (isMap(resultType)) { + throw new DeploymentException( + "Using a Map is not supported for classes annotated with '@ConfigProperties'. Consider using https://quarkus.io/guides/config-mappings instead."); + } if (isCollection(resultType)) { ResultHandle smallryeConfig = bytecodeCreator.checkCast(config, SmallRyeConfig.class); @@ -130,6 +140,11 @@ private static boolean isCollection(final Type resultType) { DotNames.SET.equals(resultType.name()); } + private static boolean isMap(final Type resultType) { + return DotNames.MAP.equals(resultType.name()) || + DotNames.HASH_MAP.equals(resultType.name()); + } + static Type determineSingleGenericType(Type type, DotName declaringClass) { if (!(type.kind() == Type.Kind.PARAMETERIZED_TYPE)) { throw new IllegalArgumentException("Type " + type.name().toString() + " which is used in class " + declaringClass diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/DotNames.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/DotNames.java index 64afa862b880a..46224bf434135 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/DotNames.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/configproperties/DotNames.java @@ -1,7 +1,9 @@ package io.quarkus.arc.deployment.configproperties; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; @@ -23,6 +25,8 @@ private DotNames() { static final DotName LIST = DotName.createSimple(List.class.getName()); static final DotName SET = DotName.createSimple(Set.class.getName()); static final DotName COLLECTION = DotName.createSimple(Collection.class.getName()); + static final DotName MAP = DotName.createSimple(Map.class.getName()); + static final DotName HASH_MAP = DotName.createSimple(HashMap.class.getName()); static final DotName ENUM = DotName.createSimple(Enum.class.getName()); static final DotName MP_CONFIG_PROPERTIES = DotName .createSimple(org.eclipse.microprofile.config.inject.ConfigProperties.class.getName()); diff --git a/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/configproperties/MapTest.java b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/configproperties/MapTest.java new file mode 100644 index 0000000000000..f7b3d4f83c7ec --- /dev/null +++ b/extensions/arc/deployment/src/test/java/io/quarkus/arc/test/configproperties/MapTest.java @@ -0,0 +1,41 @@ +package io.quarkus.arc.test.configproperties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.Map; + +import javax.enterprise.inject.spi.DeploymentException; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.arc.config.ConfigProperties; +import io.quarkus.test.QuarkusUnitTest; + +public class MapTest { + + @RegisterExtension + static final QuarkusUnitTest TEST = new QuarkusUnitTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(WithMap.class)) + .assertException(e -> { + assertEquals(DeploymentException.class, e.getClass()); + assertTrue(e.getMessage().contains("config-mappings")); + }); + + @Test + public void shouldNotBeInvoked() { + // This method should not be invoked + fail(); + } + + @ConfigProperties + public static class WithMap { + + public String name; + public Map other; + } +}