diff --git a/implementation/src/main/java/io/smallrye/config/ConfigMappingContext.java b/implementation/src/main/java/io/smallrye/config/ConfigMappingContext.java index 906597950..384ed5a36 100644 --- a/implementation/src/main/java/io/smallrye/config/ConfigMappingContext.java +++ b/implementation/src/main/java/io/smallrye/config/ConfigMappingContext.java @@ -2,6 +2,7 @@ import static io.smallrye.config.ConfigValidationException.Problem; import static io.smallrye.config.common.utils.StringUtil.unindexed; +import static java.util.Collections.EMPTY_MAP; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.UndeclaredThrowableException; @@ -12,6 +13,7 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -591,8 +593,12 @@ public Object apply(final String propertyName) { if (defaultValue == null) { // TODO - We should use getValues here, but this makes the Map to be required. This is a breaking change - return config.getOptionalValues(propertyName, keyConverter, valueConverter, HashMap::new) - .orElse(new HashMap<>()); + try { + return config.getOptionalValues(propertyName, keyConverter, valueConverter, HashMap::new) + .orElse(EMPTY_MAP); + } catch (NoSuchElementException e) { // Can be thrown by MapConverter, but mappings shouldn't use inline map values + return EMPTY_MAP; + } } else { IntFunction> mapFactory = new IntFunction<>() { @Override @@ -600,8 +606,12 @@ public Map apply(final int value) { return new MapWithDefault<>(valueConverter.convert(defaultValue)); } }; - return config.getOptionalValues(propertyName, keyConverter, valueConverter, mapFactory) - .orElse(mapFactory.apply(0)); + try { + return config.getOptionalValues(propertyName, keyConverter, valueConverter, mapFactory) + .orElse(mapFactory.apply(0)); + } catch (NoSuchElementException e) { // Can be thrown by MapConverter, but mappings shouldn't use inline map values + return mapFactory.apply(0); + } } } }; diff --git a/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java b/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java index 010c64b33..ea8492a50 100644 --- a/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java +++ b/implementation/src/test/java/io/smallrye/config/ConfigMappingInterfaceTest.java @@ -2573,14 +2573,27 @@ interface IgnorePathsRecursive { @Test void nestedLeafsMaps() { SmallRyeConfig config = new SmallRyeConfigBuilder() + .withSources(config("maps.one.two", "value")) + .withMapping(NestedLeadfsMaps.class) + .build(); + NestedLeadfsMaps mapping = config.getConfigMapping(NestedLeadfsMaps.class); + assertEquals("value", mapping.doubleMap().get("one").get("two")); + + config = new SmallRyeConfigBuilder() .withSources(config( - "maps.one.two", "value", "maps.one.two.three", "value")) .withMapping(NestedLeadfsMaps.class) .build(); + mapping = config.getConfigMapping(NestedLeadfsMaps.class); + assertEquals("value", mapping.tripleMap().get("one").get("two").get("three")); - NestedLeadfsMaps mapping = config.getConfigMapping(NestedLeadfsMaps.class); - + config = new SmallRyeConfigBuilder() + .withSources(config( + "maps.one.two", "value", + "maps.one.two.three", "value")) + .withMapping(NestedLeadfsMaps.class) + .build(); + mapping = config.getConfigMapping(NestedLeadfsMaps.class); assertEquals("value", mapping.doubleMap().get("one").get("two")); assertEquals("value", mapping.tripleMap().get("one").get("two").get("three")); }