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
BootstrapConfigFileApplicationListenerto make sure that theBootstrapConfigFileApplicationListeneralways is executed after theConfigDataEnvironmentPostProcessor.The reason
The
BootstrapConfigFileApplicationListenerrelies on theEnvironment.activeProfilesto have been set correctly, like for instance with theSpringApplication.additionalProfiles. The environment post processor responsible for setting theEnvironment.activeProfilescorrectly (e.g. by adding theSpringApplication.additionalProfiles) is theorg.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor. If it runs before theBootstrapConfigFileApplicationListenerthen everything works correctly. However both theBootstrapConfigFileApplicationListenerand theConfigDataEnvironmentPostProcessorhave the exact same order so there is no guarantee in which order they run, meaning that it can also happen thatBootstrapConfigFileApplicationListeneris executed before theConfigDataEnvironmentPostProcessor, and in that case theEnvironment.activeProfilesare 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.activeProfileswill not have all profiles when theorg.springframework.cloud.bootstrap.BootstrapConfigFileApplicationListeneris executed. If there areapplication-<profile>.ymlfiles for those missing profiles, it then does not create theapplicationConfigproperty sources for those configuration files.For example, I start up the application and provide the
productionprofile as anadditionalProfile(for instance viaSpringApplicationBuilder.additionalProfile()), and I have aapplication.ymlandapplication-production.ymlon 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.ymlnow 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
BootstrapConfigFileApplicationListeneris 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.