Skip to content
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

Profiles added using @ActiveProfiles have different precedence #28530

Closed
asibross opened this issue Nov 3, 2021 · 6 comments
Closed

Profiles added using @ActiveProfiles have different precedence #28530

asibross opened this issue Nov 3, 2021 · 6 comments
Assignees
Labels
type: regression A regression from a previous release
Milestone

Comments

@asibross
Copy link

asibross commented Nov 3, 2021

See this example that demonstrates the issue:

@SpringBootTest
@ActiveProfiles("smoketest")
class SmokeTests {

    @Autowired
    private Environment environment;

    @Test
    void testProfileOrderSB25() {
        Assertions.assertArrayEquals(new String[]{"smoketest", "dev"}, environment.getActiveProfiles());
    }

    @Test
    void testProfileOrderSB23() {
        Assertions.assertArrayEquals(new String[]{"dev", "smoketest"}, environment.getActiveProfiles());
    }
}

The dev profile is activated using an EnvironmentPostProcessor.

@Order(Ordered.HIGHEST_PRECEDENCE)
public class ProfileActivationEPP implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        environment.addActiveProfile("dev");
    }
}

The different order demonstrated above will affect the order application-<profile>.properties are added and thus the value of overridden properties.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Nov 3, 2021
@mbhave mbhave self-assigned this Nov 4, 2021
@mbhave mbhave added type: bug A general bug type: regression A regression from a previous release and removed status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Nov 5, 2021
@mbhave mbhave added this to the 2.4.x milestone Nov 5, 2021
@mbhave
Copy link
Contributor

mbhave commented Nov 10, 2021

This is happening due to StandardEnvironment being used in tests instead of ApplicationServletEnvironment. When StandardEnvironment is used and a profile is added programmatically using addActiveProfile(), Spring Framework first gets all the profiles using the property spring.profiles.active. This means the profiles are added in the order smoketest and dev. With ApplicationServletEnvironment this side-effect isn't present and smoketest only gets added once the profiles are bound which results in the correct order. This affects 2.4.x as well but since the specialized environments were added in 2.5.x, we've decided to fix it in 2.5.x.

@mbhave mbhave modified the milestones: 2.4.x, 2.5.x Nov 11, 2021
@mbhave mbhave closed this as completed in 64270ec Nov 18, 2021
@mbhave mbhave modified the milestones: 2.5.x, 2.5.7 Nov 18, 2021
@wilkinsona wilkinsona changed the title Profiles added using @ActiveProfiles have different precedence since SB 2.4 Profiles added using @ActiveProfiles have different precedence Nov 18, 2021
@dmak
Copy link

dmak commented Dec 9, 2021

Dear all,
Is there a good reason why the following code has been added at SpringBootContextLoader:126:

if (environment.getClass() == StandardEnvironment.class) {
	environment = application.convertEnvironment(environment);
	applicationEnvironment = true;
}

The issue is that the test I have which was working with Spring Boot 2.5.2 does not work with 2.6.1 because the necessary profile dev is not activated:

@SpringBootTest
@ActiveProfiles("dev")
public class FilterTest {
    @Autowired
    private FilterRegistrationBean<Filter> restrictionFilter;
...

Log:

DEBUG org.springframework.boot.ApplicationServletEnvironment - Activating profiles []
...
 INFO [,,] [                ] 8584 --- [           main] a.s.b.f.FilterTest : No active profile set, falling back to default profiles: default

If modified this way it starts to work:

@SpringBootTest(properties = "spring.profiles.active:dev")
public class FilterTest {
...

The given test utilizes StandardServletEnvironment in 2.6.1 instead of StandardEnvironment in 2.5.2. Log for v2.5.2:

DEBUG org.springframework.core.env.StandardEnvironment - Activating profiles [dev]
...
  INFO [,,] [                ] 14276 --- [           main] a.s.b.f.FilterTest : The following profiles are active: dev

@wilkinsona
Copy link
Member

@dmak There must be something else going on in your application that you haven't shared. Here's what I see with Spring Boot 2.6.1:

14:09:03.319 [main] DEBUG org.springframework.boot.ApplicationServletEnvironment - Activating profiles []
14:09:03.324 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=0}

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.1)

2021-12-10 14:09:03.621  INFO 62633 --- [           main] c.example.demo.Gh28530ApplicationTests   : Starting Gh28530ApplicationTests using Java 1.8.0_252 on wilkinsona-a01.vmware.com with PID 62633 (started by awilkinson in /Users/awilkinson/dev/workspaces/spring-projects/spring-boot/2.6.x/gh-28530)
2021-12-10 14:09:03.622  INFO 62633 --- [           main] c.example.demo.Gh28530ApplicationTests   : The following profiles are active: dev

If you would like us to investigate, please open a new issue and provide a complete yet minimal sample that reproduces the problem. You can share such a sample with us by zipping it up and attaching it to the issue you create or by pushing it to a separate repository on GitHub.

@dmak
Copy link

dmak commented Dec 10, 2021

I see that I was digging into a wrong place: SpringBootContextLoader.getEnvironment() always StandardEnvironment, so the issue is not in this very commit. I was debugging org.springframework.boot.context.config.Profiles#getActivatedProfiles() for a couple of hours until I get the idea. Actually I would have troubles creating a sample project to reproduce the problem as the initial project has tons of property files, YAMLs, and Java configurations... difficult to see where to start from.

Finally I got the following picture:

  • The project defines the default profile in application.yaml:
spring:
  profiles:
    active: dev
  • The project has application-test.properties which reads:
spring.profiles.active=
  • The particular test class has @ActiveProfiles("dev").

The idea behind is that I want to disable all profiles for all tests, but enable (some of) them back for certain tests.

I have a feeling that now application-test.properties has a precedence over @ActiveProfiles("dev") because once I remove the line spring.profiles.active= the problematic test starts to work, but other (previously working) tests fail.

I think above is sort of this comment in issue #28739 and the dirty solution is to replace @ActiveProfiles("dev") with @SpringBootTest(properties = "spring.profiles.active:dev"). My personal opinion would be that class annotation should override the value in property/YAML file.

@mbhave
Copy link
Contributor

mbhave commented Dec 13, 2021

@dmak It's hard to tell what the issue could be without the sample. I'll try nonetheless. Could you provide more information on where the test profile is activated? It's not clear from the above message and for application-test.properties to be picked up the test profile would need to be active.

Also please create a new issue instead of using a closed one and we can continue the conversation there.

@buddyp450
Copy link

Spring Framework first gets all the profiles using the property spring.profiles.active. This means the profiles are added in the order smoketest and dev

sorry to necro this but would you happen to know how to log out this behavior? I'm having a very hard time finding it in spring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
Development

No branches or pull requests

6 participants