Visitar URL original
Profiles added using @ActiveProfiles have different precedence · Issue #28530 · spring-projects/spring-boot · GitHub
Skip to content

Profiles added using @ActiveProfiles have different precedence #28530

Closed

Description

@asibross

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.

Activity

  1. self-assigned this
    on Nov 4, 2021
  2. added
    type: regressionA regression from a previous release
    and removed
    status: waiting-for-triageAn issue that has not yet been triaged. Contributions will not be accepted.
    on Nov 5, 2021
  3. added this to the 2.4.x milestone on Nov 5, 2021
  4. mbhave commented on Nov 10, 2021

    @mbhave
    Contributor

    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.

  5. modified the milestones: 2.4.x, 2.5.x on Nov 11, 2021
  6. added a commit that references this issue on Nov 18, 2021
    64270ec
  7. modified the milestones: 2.5.x, 2.5.7 on Nov 18, 2021
  8. changed the title [-]Profiles added using @ActiveProfiles have different precedence since SB 2.4[/-] [+]Profiles added using @ActiveProfiles have different precedence[/+] on Nov 18, 2021
  9. dmak commented on Dec 9, 2021

    @dmak

    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
    
  10. wilkinsona commented on Dec 10, 2021

    @wilkinsona
    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.

  11. dmak commented on Dec 10, 2021

    @dmak

    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.

  12. mbhave commented on Dec 13, 2021

    @mbhave
    Contributor

    @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.

  13. buddyp450 commented on Mar 25, 2022

    @buddyp450

    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

Metadata

Metadata

Assignees

Labels

type: regressionA regression from a previous release

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions