I'm working on a project that is currently setup to pull the spring.profiles.active
from an @PropertySource
using a file that is external to the project.
There is a method annotated with @Profile("!local")
and local is one of the profiles that is specified in the external file.
This appears to work correctly within 2.4.5 and the method is ignored. However after updating to 2.5.4 the method is now ignoring the profiles and running the method. Outputting environment.getActiveProfiles()
within the method shows an empty result.
Reproducer available at: https://github.com/icoffiel/property-source-issue
Comment From: wilkinsona
Thanks for the sample.
Using @PropertySource
to activate profiles has always been problematic as it can lead to different components in your application having different views of the profiles that are active. Your own sample illustrates this. If you add System.out.println(Arrays.toString(env.getActiveProfiles()));
to one()
it produces the following log output:
2021-09-17 09:32:45.003 INFO 79741 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
Should be visible
[disconnected, local]
As you can see, at one point during startup, no profiles were active so the fallback to default
has been used. This has then changed to disconnected
and local
being active. This can cause subtle and hard-to-diagnose bugs so Spring Boot 2.5 has tightened things up.
As of Spring Boot 2.5, the profiles that are active should not change once the Environment
has been prepared (unless something explicitly calls setActiveProfiles
or addActiveProfile
on ConfigurableEnvironment
). This ensures that all components during startup see a consistent view of the active profiles, removing the risk of some components acting as if a profile is active and others active as if it is not active.
I would recommend removing your use of @PropertySource
to activate profiles. Instead, you should declare spring.profiles.active
directly (on the command line, in application.properties
, etc) or, alternatively, you could add your test.properties
as an additional location (using spring.config.additional-location=test.properties
, for example). This will improve the situation with 2.4.x
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.5)
2021-09-17 09:40:28.306 INFO 81349 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 11.0.10 on wilkinsona-a01.vmware.com with PID 81349 (/Users/awilkinson/dev/temp/property-source-issue/build/libs/demo-0.0.1-SNAPSHOT.jar started by awilkinson in /Users/awilkinson/dev/temp/property-source-issue)
2021-09-17 09:40:28.308 INFO 81349 --- [ main] com.example.demo.DemoApplication : The following profiles are active: disconnected,local
Should be visible
[disconnected, local]
2021-09-17 09:40:28.645 INFO 81349 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.63 seconds (JVM running for 0.948)
And in 2.5.x as well:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.4)
2021-09-17 09:43:16.638 INFO 81707 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 11.0.10 on wilkinsona-a01.vmware.com with PID 81707 (/Users/awilkinson/dev/temp/property-source-issue/build/libs/demo-0.0.1-SNAPSHOT.jar started by awilkinson in /Users/awilkinson/dev/temp/property-source-issue)
2021-09-17 09:43:16.640 INFO 81707 --- [ main] com.example.demo.DemoApplication : The following profiles are active: disconnected,local
Should be visible
[disconnected, local]
2021-09-17 09:43:17.013 INFO 81707 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.675 seconds (JVM running for 1.0)
As you can see, the profiles logged as active by DemoApplication
now match those that are seen as active within your TestConfig
class.
Comment From: icoffiel
Thanks @wilkinsona for the quick triage, and detailed explanation!