Environment: - Spring Boot: 1.5.9.RELEASE - Java: 1.8.0_151 - Maven: 3.5.0 - Linux Ubuntu 4.10.0-42-generic
From what I can understand, there seems to be a bug in how properties are resolved when spring.profiles.include
is present in a property file. If spring.profiles.include
is present in a property file, property overrides done in profile-specific (application-<profile>.properties
) files are ignored.
To re-produce the issue, please follow the steps below:
1. Download the attached archive file: spring-profiles.zip
2. UnZip the archive file
3. Build the test code: mvn clean install
Then, run the test using the command mvn -Dspring.profiles.active=common,profile1 spring-boot:run
The test will output something similar to the below:
17-12-19 Tue 22:19:24.339 INFO RunSpring : The following profiles are active: common,profile1
17-12-19 Tue 22:19:24.820 INFO PropertyOverrideByProfile : Property1='default1' (expecting 'default1')
17-12-19 Tue 22:19:24.820 INFO PropertyOverrideByProfile : Property2='application2' (expecting 'application2')
17-12-19 Tue 22:19:24.821 INFO PropertyOverrideByProfile : Property3='common3' (expecting 'common3')
17-12-19 Tue 22:19:24.821 INFO PropertyOverrideByProfile : Property4='profile4' (expecting 'profile4')
17-12-19 Tue 22:19:24.821 INFO PropertyOverrideByProfile : Property5='local5' (expecting 'local5')
17-12-19 Tue 22:19:24.824 INFO PropertyOverride : Property1='default1' (expecting 'default1')
17-12-19 Tue 22:19:24.824 INFO PropertyOverride : Property2='application2' (expecting 'application2')
17-12-19 Tue 22:19:24.824 INFO PropertyOverride : Property3='common3' (expecting 'common3')
17-12-19 Tue 22:19:24.824 INFO PropertyOverride : Property4='profile4' (expecting 'profile4')
17-12-19 Tue 22:19:24.824 INFO PropertyOverride : Property5='local5' (expecting 'local5')
17-12-19 Tue 22:19:24.998 INFO RunSpring : Started RunSpring in 0.984 seconds (JVM running for 3.113)
Now, un-comment the first line in the application-profile1.properties
file (the one under src/main/resources
) and build the code again. Finally, re-run the test using the command mvn -Dspring.profiles.active=profile1 spring-boot:run
The test will output something similar to the below:
17-12-19 Tue 22:20:17.562 INFO RunSpring : The following profiles are active: common,profile1
17-12-19 Tue 22:20:18.042 INFO PropertyOverrideByProfile : Property1='default1' (expecting 'default1')
17-12-19 Tue 22:20:18.042 INFO PropertyOverrideByProfile : Property2='application2' (expecting 'application2')
17-12-19 Tue 22:20:18.042 INFO PropertyOverrideByProfile : Property3='common3' (expecting 'common3')
17-12-19 Tue 22:20:18.042 INFO PropertyOverrideByProfile : Property4='common4' (expecting 'profile4')
17-12-19 Tue 22:20:18.042 INFO PropertyOverrideByProfile : Property5='common5' (expecting 'local5')
17-12-19 Tue 22:20:18.044 INFO PropertyOverride : Property1='default1' (expecting 'default1')
17-12-19 Tue 22:20:18.044 INFO PropertyOverride : Property2='application2' (expecting 'application2')
17-12-19 Tue 22:20:18.044 INFO PropertyOverride : Property3='common3' (expecting 'common3')
17-12-19 Tue 22:20:18.044 INFO PropertyOverride : Property4='common4' (expecting 'profile4')
17-12-19 Tue 22:20:18.044 INFO PropertyOverride : Property5='common5' (expecting 'local5')
17-12-19 Tue 22:20:18.177 INFO RunSpring : Started RunSpring in 0.933 seconds (JVM running for 2.938)
As indicated above, both have the same profile ordering. Hence, I would assume they should both produce the same output. However, the values for Property4 and Property5 are only as expected in the first test run.
NB!
In the first test run, I explicitly specify 'common' and 'profile1' as active profiles on the command line. While in the second test run, only 'profile1' is set as active on the command line. However, now the 'common' profile is added (included) by un-commenting the line spring.profiles.include=common
at the top of the application-profile1.properties
file.
Comment From: pibakke
Just wanted to add ... the class PropertyOverride
is using traditional Spring XML files and constructor injection for the the properties. While, the class PropertyOverrideByProfile
is using @Profile and @Value annotations and component scanning.
Both alternatives seems to produce the same output.
Comment From: mbhave
@pibakke I'm not sure I understand which part you think is a bug.
If spring.profiles.include is present in a property file, property overrides done in profile-specific (application-
.properties) files are ignored.
They aren't being ignored. In this example, the properties from common
take precedence when it is added using spring.profiles.include
.
spring.profiles.include
is meant for unconditionally adding active profiles so IMO this is expected behavior.
Comment From: pibakke
Hi Madhura
I have read through the documentation found at Spring Boot features (chapter '25.1 Adding active profiles' in particular) and I still think there is a bug.
You are right in that property-overrides done in application-common.properties
are being picked up (as they should) in both cases. This is verified in the output for Property3. However, the property overrides done in application-profile1.properties
(src/main/resources and "root" directories) are NOT being honored in the second example (see output for Property4 and Property5).
Please not that Spring Boot detemines the same (correct) active profiles and profile ordering in both cases as evident in the log statement The following profiles are active: common,profile1
. Hence, I would expect the output to be the same in both cases.
As you mention, the documentation states:
Sometimes it is useful to have profile-specific properties that add to the active profiles rather than replace them. The spring.profiles.include property can be used to unconditionally add active profiles.
In my interpretation, I focus on the statement 'add rather than replace'. While the Spring Boot implementation seem to focus on the statement 'unconditionally'. In Spring Boot, profiles are used for activating profile specific beans (works as expected) and property resolution. My issue is with the property resolution part of Spring Boot.
Comment From: philwebb
I believe the work we did in 2.0 for #8011 and #12159 has fixed this.
Upgrading the POM I see this on the second run:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.0.RELEASE)
18-03-28 Wed 14:40:51.467 INFO RunSpring : Starting RunSpring on pwmb16 with PID 97954 (/Users/pwebb/Downloads/spring-profiles/target/classes started by pwebb in /Users/pwebb/Downloads/spring-profiles)
18-03-28 Wed 14:40:51.469 INFO RunSpring : The following profiles are active: common,profile1
18-03-28 Wed 14:40:51.867 INFO PropertyOverrideByProfile : Property1='default1' (expecting 'default1')
18-03-28 Wed 14:40:51.867 INFO PropertyOverrideByProfile : Property2='application2' (expecting 'application2')
18-03-28 Wed 14:40:51.867 INFO PropertyOverrideByProfile : Property3='common3' (expecting 'common3')
18-03-28 Wed 14:40:51.867 INFO PropertyOverrideByProfile : Property4='profile4' (expecting 'profile4')
18-03-28 Wed 14:40:51.867 INFO PropertyOverrideByProfile : Property5='local5' (expecting 'local5')
18-03-28 Wed 14:40:51.869 INFO PropertyOverride : Property1='default1' (expecting 'default1')
18-03-28 Wed 14:40:51.869 INFO PropertyOverride : Property2='application2' (expecting 'application2')
18-03-28 Wed 14:40:51.870 INFO PropertyOverride : Property3='common3' (expecting 'common3')
18-03-28 Wed 14:40:51.870 INFO PropertyOverride : Property4='profile4' (expecting 'profile4')
18-03-28 Wed 14:40:51.870 INFO PropertyOverride : Property5='local5' (expecting 'local5')
18-03-28 Wed 14:40:51.990 INFO RunSpring : Started RunSpring in 0.858 seconds (JVM running for 2.966)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.023 s
[INFO] Finished at: 2018-03-28T14:40:51-07:00
[INFO] Final Memory: 25M/312M
[INFO] ------------------------------------------------------------------------
Comment From: pibakke
Hi Phil
Thanks for looking into this issue.
Unfortunately, the issue seems NOT to be fixed in Spring 2.0.0.RELEASE. I have verified this by following the steps in my initial post (un-commenting the first line in application-profile1.properties
file). This time I also changed the pom.xml
file to 2.0.0.RELEASE
.
Building and executing the test with the command line mvn -Dspring.profiles.active=profile1 spring-boot:run
produces the output listed below, with the un-expected values for Property4 and Property5.
This differs from the output you provided in your post. I would guess the reason is that you specified the common
profile on the command line when you executed the test.
`` . ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _
| \ \ \ \
\/ )| |)| | | | | || (_| | ) ) ) )
' || .__|| ||| |_, | / / / /
=========|_|==============|/=///_/
:: Spring Boot :: (v2.0.0.RELEASE)
18-04-03 ti 09:34:53.027 INFO RunSpring : Starting RunSpring on NO0434 with PID 3204 (C:\projects\spring-profiles\target\classes started by piba in C:\projects\spring-profiles) 18-04-03 ti 09:34:53.042 INFO RunSpring : The following profiles are active: common,profile1 18-04-03 ti 09:34:53.667 INFO PropertyOverrideByProfile : Property1='default1' (expecting 'default1') 18-04-03 ti 09:34:53.683 INFO PropertyOverrideByProfile : Property2='application2' (expecting 'application2') 18-04-03 ti 09:34:53.683 INFO PropertyOverrideByProfile : Property3='common3' (expecting 'common3') 18-04-03 ti 09:34:53.683 INFO PropertyOverrideByProfile : Property4='common4' (expecting 'profile4') 18-04-03 ti 09:34:53.683 INFO PropertyOverrideByProfile : Property5='common5' (expecting 'local5') 18-04-03 ti 09:34:53.683 INFO PropertyOverride : Property1='default1' (expecting 'default1') 18-04-03 ti 09:34:53.699 INFO PropertyOverride : Property2='application2' (expecting 'application2') 18-04-03 ti 09:34:53.699 INFO PropertyOverride : Property3='common3' (expecting 'common3') 18-04-03 ti 09:34:53.699 INFO PropertyOverride : Property4='common4' (expecting 'profile4') 18-04-03 ti 09:34:53.714 INFO PropertyOverride : Property5='common5' (expecting 'local5') 18-04-03 ti 09:34:54.730 INFO RunSpring : Started RunSpring in 2.48 seconds (JVM running for 16.254) [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 12.935 s [INFO] Finished at: 2018-04-03T09:34:54+02:00 [INFO] Final Memory: 18M/115M [INFO] ------------------------------------------------------------------------```
Comment From: wilkinsona
Re-opening so that we don't forget to double-check.
Comment From: pibakke
Excellent ... please let me know if you need additional information.
Comment From: wilkinsona
I believe I'm seeing the same behaviour as @pibakke on the second run:
$: cat src/main/resources/application-profile1.properties; mvn clean -Dspring.profiles.active=profile1 spring-boot:run
spring.profiles.include=common
# Override property value
my.spring.profile.property4=profile4
my.spring.profile.property5=profile5
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< no.test:spring-profiles >-----------------------
[INFO] Building Spring Profiles 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ spring-profiles ---
[INFO] Deleting /Users/awilkinson/Downloads/spring-profiles/target
[INFO]
[INFO] >>> spring-boot-maven-plugin:2.0.0.RELEASE:run (default-cli) > test-compile @ spring-profiles >>>
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ spring-profiles ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 5 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ spring-profiles ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 3 source files to /Users/awilkinson/Downloads/spring-profiles/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ spring-profiles ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /Users/awilkinson/Downloads/spring-profiles/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ spring-profiles ---
[INFO] No sources to compile
[INFO]
[INFO] <<< spring-boot-maven-plugin:2.0.0.RELEASE:run (default-cli) < test-compile @ spring-profiles <<<
[INFO]
[INFO]
[INFO] --- spring-boot-maven-plugin:2.0.0.RELEASE:run (default-cli) @ spring-profiles ---
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.0.RELEASE)
18-04-03 Tue 10:23:50.870 INFO RunSpring : Starting RunSpring on aw-rmbp.local with PID 89458 (/Users/awilkinson/Downloads/spring-profiles/target/classes started by awilkinson in /Users/awilkinson/Downloads/spring-profiles)
18-04-03 Tue 10:23:50.873 INFO RunSpring : The following profiles are active: common,profile1
18-04-03 Tue 10:23:51.391 INFO PropertyOverrideByProfile : Property1='default1' (expecting 'default1')
18-04-03 Tue 10:23:51.391 INFO PropertyOverrideByProfile : Property2='application2' (expecting 'application2')
18-04-03 Tue 10:23:51.391 INFO PropertyOverrideByProfile : Property3='common3' (expecting 'common3')
18-04-03 Tue 10:23:51.391 INFO PropertyOverrideByProfile : Property4='common4' (expecting 'profile4')
18-04-03 Tue 10:23:51.391 INFO PropertyOverrideByProfile : Property5='common5' (expecting 'local5')
18-04-03 Tue 10:23:51.393 INFO PropertyOverride : Property1='default1' (expecting 'default1')
18-04-03 Tue 10:23:51.393 INFO PropertyOverride : Property2='application2' (expecting 'application2')
18-04-03 Tue 10:23:51.393 INFO PropertyOverride : Property3='common3' (expecting 'common3')
18-04-03 Tue 10:23:51.394 INFO PropertyOverride : Property4='common4' (expecting 'profile4')
18-04-03 Tue 10:23:51.394 INFO PropertyOverride : Property5='common5' (expecting 'local5')
18-04-03 Tue 10:23:51.521 INFO RunSpring : Started RunSpring in 0.954 seconds (JVM running for 3.471)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.521 s
[INFO] Finished at: 2018-04-03T10:23:51+01:00
[INFO] ------------------------------------------------------------------------
Comment From: wilkinsona
Let's see if there's something more we can do that'll fix this in 2.0.x
Comment From: inad9300
@pibakke, has this issue been solved for you? I'm experiencing it as well with 2.3.2.RELEASE...
😮 It turns out, this configuration injects Z
for target.property
when activating Y
...
spring.profiles: X
spring.profiles.include: Z
target.property: X
---
spring.profiles: Y
spring.profiles.include: X
target.property: Y
---
spring.profiles: Z
target.property: Z
While this one injects X
for the same property, with the same active profile...
spring.profiles: X
spring.profiles.include: Z
target.property: X
---
spring.profiles: Y
spring.profiles.include: Z, X
target.property: Y
---
spring.profiles: Z
target.property: Z
While the expected value in both cases is Y
!
Comment From: boostmerlin
the problem still exists in id 'org.springframework.boot' version '2.4.1', but test ok in 2.1.7.RELEASE
Comment From: wilkinsona
@boostmerlin Could you try 2.4.2 please? If your problem still occurs, please open a new issue and provide a minimal sample that reproduces the problem you're seeing.