smallrye / smallrye-config

SmallRye Config - A Java Configuration library
Apache License 2.0
164 stars 119 forks source link

Map support example seems not to be working (getting NoSuchElementException: SRCFG00014) #926

Closed SoerenHenning closed 1 year ago

SoerenHenning commented 1 year ago

Hi, I am trying to reproduce the example of the Map Support example from the documentation. However, I get an NoSuchElementException when trying to read a configuration value as Map. I use version 3.2.1 and the programmatical access without any CDI involved in my setup.

In more detail, I performed the following steps:

  1. I added
    server.reasons=200=OK;201=Created

    to my META-INF/microprofile-config.properties file.

  2. I have a simple main method with the following code:
    final Config config = ConfigProvider.getConfig();
    final SmallRyeConfig smallRyeConfig = config.unwrap(SmallRyeConfig.class);
    System.out.println(smallRyeConfig.getValue("server.reasons", String.class));
    System.out.println(smallRyeConfig.getValues("server.reasons", Integer.class, String.class));
  3. Contrary to what I expect, I get the following output
    200=OK;201=Created
    Exception in thread "main" java.util.NoSuchElementException: SRCFG00014: The config property server.reasons is required but it could not be found in any config source
    at io.smallrye.config.SmallRyeConfig.getValues(SmallRyeConfig.java:186)
        <...>
  4. Additionally, I also overrode the server.reasons by setting an environment variable SERVER.REASONS but I got the same exception.
radcortez commented 1 year ago

Unfortunately, the documentation is incorrect. The format value of server.reasons=200=OK;201=Created is only intended to be used with org.eclipse.microprofile.config.inject.ConfigProperty#defaultValue, since it can only accept a String value.

In regular config sources, like properties files, a Map is expressed like map.path.key=value. Updating your example:

SmallRyeConfig config = new SmallRyeConfigBuilder()
    .withSources(new PropertiesConfigSource(Map.of(
        "server.reasons.OK", "200", 
        "server.reasons.CREATED", "201"), "", 100))
    .build();
System.out.println(config.getValues("server.reasons", String.class, Integer.class));

This works.

I'm sorry for the inconvenience. I'll update the docs.

SoerenHenning commented 1 year ago

Alright, thank you! :)