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
Additional profiles are processed too late when legacy processing is used #25817
Additional profiles are processed too late when legacy processing is used #25817
Conversation
1aa39f5
to
bd4fa3c
Compare
...oot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java
Outdated
Show resolved
Hide resolved
Thanks for the pull request, @nguyensach. Additional profiles configured via Lines 557 to 565 in d1aaee4
IIRC, this means that they should be picked up by |
4002310
to
5ba2234
Compare
Thanks for your information!
In Spring Boot 2.4, when legacy processing is used and additional profiles configured via Lines 552 to 562 in 4ad87a8
In Spring Boot 2.3, the implementation of the method Lines 513 to 526 in 73cab9c
In Spring Boot 2.3, by the method Line 345 in 73cab9c
Then, in However, In Spring Boot 2.4, the method
In Spring Boot 2.4, when using legacy processing, the additional profiles are not picked up by ConfigFileApplicationListener without any special treatment. After rethinking about order of the additional profiles, the included profiles, the other actived profiles in the By the way, in my PR, the CI is fail at the gradle's |
@@ -558,16 +558,6 @@ protected void configurePropertySources(ConfigurableEnvironment environment, Str | |||
protected void configureProfiles(ConfigurableEnvironment environment, String[] args) { | |||
} | |||
|
|||
private void configureAdditionalProfiles(ConfigurableEnvironment environment) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The additional profiles are included in the Environment's active profiles at ConfigDataEnvironmentPostProcessor when legacy processing is used, or at ConfigDataEnvironment as below
Line 348 in 4ad87a8
this.environment.setActiveProfiles(StringUtils.toStringArray(profiles.getActive())); |
Therefore, configureAdditionalProfiles
becomes unnecessary.
@philwebb could you take a look at this one please? |
There's no auto-fix for Checkstyle problems, unfortunately. Looking at the diff, I suspect the problem is due to the changes to the imports. They need to be kept in their current ordering and not use wildcards. |
@wilkinsona Thanks for your response! I will fix it manually. |
In post-processing the given environment of ConfigDataEnvironmentPostProcessor, add SpringApplication's additional profiles that are set by programmatically into environment when legacy processing is used. This commit updates the following areas: - Add configureAdditionalProfiles method into ConfigDataEnvironmentPostProcessor, that add the additional profiles into the given environment. - When legacy processing is used, call configureAdditionalProfiles method to add the additional profiles into the given environment. - Remove unnecessary configureAdditionalProfiles method in SpringApplication. - Supplement unit test for SpringApplicationTests. Closes spring-projects#25704
5ba2234
to
aaf7092
Compare
@nguyensach This change makes sense to me. I have left some comments. Can you please take a look? |
@mbhave |
this.context = application.run(); | ||
assertThat(this.context.getEnvironment().acceptsProfiles(Profiles.of("dev"))).isTrue(); | ||
assertThat(this.context.getEnvironment().getProperty("my.property")).isEqualTo("fromdevpropertiesfile"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need this test as it is essentially a duplicate of the test below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 32 in 0893df4
* Tests to reproduce reported issues. |
According to the above comment, this test reproduces reported issues. Like you commented, it is essentially a duplicate of another test, so I will remove it.
application.setWebApplicationType(WebApplicationType.NONE); | ||
application.setAdditionalProfiles("other", "dev"); | ||
this.context = application.run(); | ||
assertThat(this.context.getEnvironment().getProperty("my.property")).isEqualTo("fromdevpropertiesfile"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test doesn't seem to be giving us much either and I don't think it is required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only want to test when there are many additional profiles rather than one.
In this test case, I want to check that which additional profile should win.
Maybe this test isn't related to the bug. Could I add this test to another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, we don't need the test for the single additional profile and we can keep this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, we don't need the test for the single additional profile and we can keep this one.
You don't need the test for the multiple additional profiles, right?
If so, I will delete this test case.
application.setWebApplicationType(WebApplicationType.NONE); | ||
this.context = application.run("--spring.profiles.active=bar,spam", "--spring.profiles.include=foo"); | ||
// Before Boot 2.4 included profiles should always be first | ||
assertThat(this.context.getEnvironment().getActiveProfiles()).containsExactly("foo", "bar", "spam"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test doesn't seem to be related to the bug that this issue is trying to address. The issue is about additionalProfiles
and I don't think this test is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test isn't related to the bug. However, I think that we are lacking test cases of the order included profiles and active profiles. So, Could I add this test to another PR?
Because of lacking test cases of the order additional profiles and active profiles, it results in #26189
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to be testing active and additional profiles though. It's testing active and included profiles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mbhave
#25817 (comment)
As your above comment, there is already a test case that tests active and included profiles when using legacy processing, so I will delete this test case.
@@ -82,6 +83,7 @@ void postProcessEnvironmentWhenNoLoaderCreatesDefaultLoaderInstance() { | |||
verify(this.postProcessor).getConfigDataEnvironment(any(), this.resourceLoaderCaptor.capture(), any()); | |||
verify(this.configDataEnvironment).processAndApply(); | |||
assertThat(this.resourceLoaderCaptor.getValue()).isInstanceOf(DefaultResourceLoader.class); | |||
assertThat(this.environment.getActiveProfiles()).isEmpty(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nguyensach What is the reason for adding this (and similiar ones below) assertion here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In ConfigDataEnvironmentPostProcessor
, I added the below code.
It adds the additional profiles to the environment's active profiles, so I want to check the environment's active profiles here
this.context = application.run("--spring.profiles.active=bar,spam", "--spring.profiles.include=foo"); | ||
// Since Boot 2.4 included profiles should always be last | ||
assertThat(environment.getActiveProfiles()).containsExactly("bar", "spam", "foo"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test also seems unrelated to this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As my above reply, Could I add this test to another PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we already cover the active and include case in this test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mbhave
In this test case, I want to test active and included profiles when using Boot 2.4 or later without using legacy processing.
It seems that the order of the active and included profiles has to be changed since boot 2.4 or later without using legacy processing.
Could I add this test to another PR?
this.postProcessor.postProcessEnvironment(this.environment, this.application); | ||
verifyNoInteractions(this.configDataEnvironment); | ||
verify(legacyListener).addPropertySources(eq(this.environment), any(DefaultResourceLoader.class)); | ||
assertThat(this.environment.getActiveProfiles()).containsExactly("dev"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of just checking if the environment contains the additional profiles (which it does even today because SpringApplication
configures them in configureAdditionalProfiles
), we should check if the profiles are actually processed by ConfigFileApplicationListener
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the scope of ConfigDataEnvironmentPostProcessor
, I am only checking if the environment contains the additional profiles.
we should check if the profiles are actually processed by ConfigFileApplicationListener
In order to check it, I added two below tests.
https://github.com/spring-projects/spring-boot/pull/25817/files#diff-82a4d071283a2194fc5c0e8cffbdddbeda4e53d4e5676138f93b46fcaa16e516R1154-R1163
@nguyensach Sorry about that! I forgot to click on submit 🤦🏽♀️ Hopefully you can see them now. |
@mbhave Thanks for your review! I replied to all your comments. |
Additional profiles were being processed after config file processing when legacy processing was used. This commit also restores the order in which additional profiles are added when legacy processing is used. Active profiles take precedence over additional profiles. See gh-25817
Additional profiles were being processed after config file processing when legacy processing was used. This commit also restores the order in which additional profiles are added when legacy processing is used. Active profiles take precedence over additional profiles. See gh-25817
Thanks for the PR @nguyensach. This has now been merged into |
In post-processing the given environment of ConfigDataEnvironmentPostProcessor, add SpringApplication's additional profiles that are set programmatically into the given environment when legacy processing is used.
This commit updates the following areas:
Add configureAdditionalProfiles method into ConfigDataEnvironmentPostProcessor, that add the additional profiles into the given environment.
When legacy processing is used, call configureAdditionalProfiles method to add the additional profiles into the given environment.
Remove unnecessary configureAdditionalProfiles method in SpringApplication.
Supplement unit test for SpringApplicationTests.
Fixes #25704
Fixes #26189