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!