spring-boot: SpringProfileDocumentMatcher does not work as expected

The following issue appears with Spring Boot 1.4.3:

Given a YAML configuration like

someValue: 4711

example:
    greeting: Hello, World!
---
spring:
    profiles: demo1
example:
    greeting: Hello, Demo1!

---
spring:
    profiles: demo2
example:
    greeting: Hello, Demo2!

---
spring:
    profiles: "!demo2"
someValue: 2109

(Full configuration and properties class in example project extconfig see: application.yml and ExampleConfiguration)

and run with java -jar target/extconfig.jar I expect someValue to be 2109: The negated profile !demo2 overwriting the value of 4711.

run with java -jar target/extconfig.jar --spring.profiles.active=demo2 I expect someValue to be 4711 as it is set in the default, not overwritten in demo2 (not set) and not overwritten bei !demo2. The same is expected for the other parts of the configuration.

In contrast to my expectations, I get in both cases 2109.

The project linked above contains a test class NegatedProfilesTest that fails.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 16 (16 by maintainers)

Commits related to this issue

Most upvoted comments

Over the weekend it occurred to me that it was only sensible to handle spring.profiles.include in this code as well. After a bit of work I came to the conclusion that it was necessary to determine the active profile information in a first pass before coming back to actually load the profile-specific subdocuments; the branch referenced above now reflects this.

I’ve fixed this in a slightly different way in the end (at least I think it’s fixed). The SpringProfileDocumentMatcher has quite a lot of complex logic so I’ve decided to drop it entirely in 2.0. I’m pretty sure that we’re the only people really using it. I’ve replaced it with two new matchers that are much simpler in design. This approach doesn’t introduce too much complexity, but it also doesn’t quite work if profiles are activated in other profiles. The ...cascade... test in Madhura’s branch now fail.

The reason for this is that on the first call, there are no profiles set. This means that any negative sections will match. So given this file:

spring:
  profiles:
    active:
      - A
      - B

+---
spring.profiles: "!A"
not-a: true      

You will get a not-a property because the at the time the file is loaded, profile A isn’t active.

I think that’s actually pretty consistent with other yaml loading that we do and I prefer it to checking for active profiles when properties are resolved. For the sake of simplicity, I think we should live with that restriction.

@mbhave I will try to take a look at that this week and get back up to speed. Thanks for the attention!

I thought of another way to break the code I had in place, e.g.: application.yml:

spring.profiles:
  - "!foo"

application-bar.yml

spring:
  profiles:
    include:
      - foo

My branch https://github.com/mbenson/spring-boot/tree/yaml-negation now accounts for this case, whenever the team is ready for a discussion. 😃

Okay, on my third attempt I have some code that seems to be working. I’m not submitting a PR just yet because I think my approach is invasive enough that it bears discussion, but as I said it’s not a simple problem to solve within the confines of the existing APIs: https://github.com/mbenson/spring-boot/tree/yaml-negation