-
Notifications
You must be signed in to change notification settings - Fork 705
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
Fixed order of the BootstrapConfigFileApplicationListener
so that it always runs after the ConfigDataEnvironmentPostProcessor
#1213
Conversation
Previously `BootstrapConfigFileApplicationListener` had the same order as `ConfigDataEnvironmentPostProcessor`. This made it indeterminable which one would run first. However, the `BootstrapConfigFileApplicationListener` relies on the `ConfigDataEnvironmentPostProcessor` to make sure the `Environment.activeProfiles` are correctly set, so it must always run after the `ConfigDataEnvironmentPostProcessor`.
…tProcessor.DEFAULT_ORDER` so that any accidental overflow results in an exception
@spencergibb Hi, I was wondering when this PR is going to be discussed with the team. It has been op for quite some months now. Kind regards, |
I know @ryanjbaxter has been looking at similar issues. I'll have him look at it. |
Have you retested this with Spring Cloud 2022.0.3? The logic around activating profiles has changed. |
@ryanjbaxter Thanks for getting back to me. I wasn't aware of those changes. I will take a look. |
@ryanjbaxter I looked at it again, and I still think this issue can occur, because the With the debugger I created the following stracktraces to show where the active profiles are added first via the
In this example everything works out, because the |
…t always runs after the `ConfigDataEnvironmentPostProcessor` (#1213) * Changed order of `BootstrapConfigFileApplicationListener` Previously `BootstrapConfigFileApplicationListener` had the same order as `ConfigDataEnvironmentPostProcessor`. This made it indeterminable which one would run first. However, the `BootstrapConfigFileApplicationListener` relies on the `ConfigDataEnvironmentPostProcessor` to make sure the `Environment.activeProfiles` are correctly set, so it must always run after the `ConfigDataEnvironmentPostProcessor`. * Using `Math.addExact` for adding one to the `ConfigDataEnvironmentPostProcessor.DEFAULT_ORDER` so that any accidental overflow results in an exception
Also cherry picked this change to 4.0.x as well |
This PR changes the order of the
BootstrapConfigFileApplicationListener
to make sure that theBootstrapConfigFileApplicationListener
always is executed after theConfigDataEnvironmentPostProcessor
.The reason
The
BootstrapConfigFileApplicationListener
relies on theEnvironment.activeProfiles
to have been set correctly, like for instance with theSpringApplication.additionalProfiles
. The environment post processor responsible for setting theEnvironment.activeProfiles
correctly (e.g. by adding theSpringApplication.additionalProfiles
) is theorg.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor
. If it runs before theBootstrapConfigFileApplicationListener
then everything works correctly. However both theBootstrapConfigFileApplicationListener
and theConfigDataEnvironmentPostProcessor
have the exact same order so there is no guarantee in which order they run, meaning that it can also happen thatBootstrapConfigFileApplicationListener
is executed before theConfigDataEnvironmentPostProcessor
, and in that case theEnvironment.activeProfiles
are not set correctly.What happens if the two listeners are executed in the wrong order
If the listeners are executed in the wrong order, the
Environment.activeProfiles
will not have all profiles when theorg.springframework.cloud.bootstrap.BootstrapConfigFileApplicationListener
is executed. If there areapplication-<profile>.yml
files for those missing profiles, it then does not create theapplicationConfig
property sources for those configuration files.For example, I start up the application and provide the
production
profile as anadditionalProfile
(for instance viaSpringApplicationBuilder.additionalProfile()
), and I have aapplication.yml
andapplication-production.yml
on the classpath. If I then look at the property sources, I expect to see the following property source ordering (I left out the unrelated property sources):Config resource 'class path resource [application-production.yml]' via location 'optional:classpath:/'
Config resource 'class path resource [application.yml]' via location 'optional:classpath:/'
applicationConfig: [classpath:/application-production.yml]
applicationConfig: [classpath:/application.yml]
However what I sometimes get is:
applicationConfig: [classpath:/application.yml]
Config resource 'class path resource [application-production.yml]' via location 'optional:classpath:/'
Config resource 'class path resource [application.yml]' via location 'optional:classpath:/'
So you can see that the
application.yml
now has the highest order, and theapplicationConfig: [classpath:/application-production.yml]
property source is missing. This means the wrong property values will be returned for the properties defined inapplication-production.yml
.Side question:
I wonder why the
BootstrapConfigFileApplicationListener
is even needed to create these property sources, as what I can see is that Spring Boot itself also creates the property sources for these files. So now there are always two property sources for every configuration file.