-
Notifications
You must be signed in to change notification settings - Fork 40.8k
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
Binder provided by ConfigDataLocationResolver does not support profiles on classpath #43514
Comments
This is actually by design as we only want that binder to provide access to values that have been contributed so far. We don't want to allow |
Hey @philwebb , Thanks on quick response and explanation. I was expecting this behaviour however I found it different that is why I raised the question. Reading now I have not expressed myself best so I will try to do so now.
If I included I was expecting that I can provide sample application of the issue if it would explain it better. Edit: I am running my app with env variable -> |
Could you provide the sample application. I think it would help my understanding of the issue. Thanks! |
Ofcourse, here you go. If you need anything more please let me know. https://github.com/MatejNedic/Spring-boot-issue-43514 Please run with env variable After that uncomment values You won't see logs since enabled will be picked up by binder. |
Thanks for the sample, it has helped a lot! I still think this is working as designed and the problem might be that The config data loading code is quite complicated. It attempts to build a tree of If you imagine a tree structure, the initial two nodes are as follows:
As files are loaded, imports add nodes to the tree. So for example, if in
If in
The important thing is that the tree represents the order that property sources are added and hence overriding happens correctly. A value in bar.properties, overrides the file config, foo.properties and classpath config. Some documentation exists on this at https://docs.spring.io/spring-boot/reference/features/external-config.html#features.external-config.files.importing In your case, what is happening is you have a
Once we've done the first pass, we have profile properties and we enable the dev profile and do a second sweep. In the original version of your app we get:
I think we end up adding that I'm not sure what the best way to fix this is, but I think I'd recommend moving the I'm also wondering if we should try and be stricter in Spring Boot and provide the same binder to |
I've opened #43533 to see if we can pass in the same binder. |
Thanks @philwebb so much on extensive explanation!!! Really appreciate it! Makes sense now since our Basically bug on our side, will have to implement resolve(), since it does not align currently with spring boot! Are you accepting PRs for #43533 ? I know it might be complex but I am willing to try it out. |
Thanks for the offer of a PR, but I think I might need to take it on since it's such a complicated bit of code. We also can't merge anything until we create the |
When implementing custom
spring.config.import
solution and implementingConfigDataLocationResolver
,Binder
retrieved fromConfigDataLocationResolverContext.getBinder
method won't respect profiles resources loaded fromclasspath
.Debug context:
When
ConfigDataLocationResolver.resolveProfileSpecific
is called it passes instance ofConfigDataLocationResolverContext
which hasgetBinder
method. WhengetBinder()
is called it will execute the following.Returned
binder
instance will bind prefix to a given class, but it will not look for profile specific properties, only default ones are taken into account. Meaning onlyapplication.properties
is taken into account.So if user has active dev profile and
application-dev.properties
with a following value.Endpoint will not be mapped properly to given class, to be specific it won't bind it to an endpoint field since it is not taking dev profile file into an account.
Classpath
and/config
ConfigDataLocationResolver
are taken into account before any other customConfigDataLocationResolver
implementation. This means thatStandardConfigDataLocationResolver
will be called first before anything else.Currently
/config
properties are loaded first than my customConfigDataLocationResolver
implementation. This implementation getsbinder
which can look only at defaultapplication.properties
. After thisStandardConfigDataLocationResolver
is called again withclasspath
resource lookup. Which meansBinder
does not have access toresources/application-dev.yaml
.One way to go around this is to provide all values which directly affect
ConfigDataLocationResolver
implementation in a single file.I can still have application-dev.properties loaded for different properties that don't impact the
ConfigDataLocationResolver
implementations.Everything works tho if file
application-dev.properties
is located under/config
since it is loaded first.I am willing to do contribution.
Docs I checked.
The text was updated successfully, but these errors were encountered: