Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Micronaut PropertySourceLoader resolution unpredictable when using micronaut.config.files #13383

Open
mattlong-finocomp opened this issue Feb 8, 2024 · 1 comment
Assignees

Comments

@mattlong-finocomp
Copy link

mattlong-finocomp commented Feb 8, 2024

Expected Behavior

When using Micronaut beans (conditional beans in my case) in a Grails application and micronaut.config.files for external configuration files, resolution of config items within the external configuration file should be consistent.

Actual Behaviour

With the introduction of MicronautYamlPropertySourceLoader in Grails 6.0, config resolution is unpredictable for Micronaut beans in Grails applications when using micronaut.config.files configuration.

Micronaut's DefaultEnvironment#evaluatePropertySourceLoaders can only populate a single PropertySourceLoader per extension which it stores in loaderByFormatMap. The PropertySourceLoader that is populated seems random based on the order in which the classloader finds matching service configurations in META-INF/services files.

Depending on which order the service configurations are loaded the map may end up with one of MicronautYamlPropertySourceLoader OR YamlPropertySourceLoader.

MicronautYamlPropertySourceLoader requires the config be nested under environments.<env>, while YamlPropertySourceLoader requires the config to be at the top level and not nested.

I'm unaware of a way to influence the order in which the classloader loads those service configurations, and Micronaut doesn't seem to take into account the Orderable nature of the PropertySourceLoaders when storing them in the map.

When loading PropertySources from default locations ie classpath:/ and file:config/, Micronaut will attempt to use each PropertySourceLoader in sequence, whereas when processing any files configured in micronaut.config.files it will only use the PropertySourceLoader stored in the loaderByFormatMap.

I suspect that a fix will be required in Micronaut but this appears to only impact Grails applications because of Grails custom PropertySourceLoader implementations that clash with the ones provided by Micronaut itself.

Steps To Reproduce

  1. Create a conditional Micronaut bean based on some property being enabled.
  2. Configure the bean to be disabled in grails-app/conf/application.yml
  3. Create an application-foo.yml somewhere outside of the classpath of the application which sets config to enable the bean with the config nested under environments.foo and also at the root level. Comment out the root level configuration.
  4. Start the application with environment variables configuring MICRONAUT_CONFIG_FILES to point to the absolute path of application-foo.yml and GRAILS_ENV set to 'foo'. You can also set MICRONAUT_ENVIRONMENTS to 'foo' but it makes no difference.
  5. Observe that the bean is not enabled (Consider setting io.micronaut.context.condition log level to DEBUG). If the bean is enabled, comment out the config enabling it that is nested under environments.foo and uncomment the root level config.

You can observe the functionality working by removing MICRONAUT_CONFIG_FILES and application-foo.yml is either on the classpath or in the config directory relative to the running application.

Environment Information

OS: Pop!OS 22.04
Java: 11.0.11-hs-adpt

Example Application

N/A

Version

6.1.2

@mattlong-finocomp
Copy link
Author

I found that this is also likely impacting config resolution for injected configuration values.
I don't think that micronaut.config.files has any impact in this situation.
The injected value is looked up from the PropertySourcePropertyResolver catalog and this is populated as we iterate through the PropertySourceLoaders which we can't control the order of.
I think the root cause is the same but I can open a separate issue if you'd prefer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants