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

Order of map property in application yaml is no longer preserved #21470

Closed
mengelbrecht opened this issue May 15, 2020 · 5 comments
Closed

Order of map property in application yaml is no longer preserved #21470

mengelbrecht opened this issue May 15, 2020 · 5 comments
Assignees
Labels
type: regression A regression from a previous release
Milestone

Comments

@mengelbrecht
Copy link

Scenario:
A ConfigurationProperties class contains a Map<String, String> property.
The contents of the map are specified in an application.yml file.

Expected behavior:
The order of the map entries (as specified in the yaml file) is preserved. This is the case with Spring-Boot 2.2.7.

Actual behavior:
The order of the map entries (as specified in the yaml file) is not preserved. This is the case with Spring-Boot 2.3.0.

Minimal project to reproduce:

DemoApplication.kt:

package com.example.demo

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.boot.context.properties.ConstructorBinding
import org.springframework.boot.runApplication
import javax.annotation.PostConstruct

@ConfigurationProperties("test")
@ConstructorBinding
class Properties(
    val map: Map<String, String>
)

@SpringBootApplication
@ConfigurationPropertiesScan
class DemoApplication {
    @Autowired
    private lateinit var properties: Properties

    @PostConstruct
    fun postInit() {
        println(properties.map.toString())
    }
}

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

application.yml:

test:
  map:
    foo: foo
    baz: baz
    bar: bar

Spring-Boot 2.2.7 prints: {foo=foo, baz=baz, bar=bar}
Spring-Boot 2.3.0 prints: {baz=baz, bar=bar, foo=foo}

Demo Project: demo.zip

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 15, 2020
@wilkinsona
Copy link
Member

wilkinsona commented May 15, 2020

Thanks for the report. I'm not sure that we've ever deliberately guaranteed the ordering, but I can see that it's changed in 2.3. I get {foo=foo, baz=baz, bar=bar} with RC1 (the same as 2.2.7) so, whatever the cause, it's recent.

@wilkinsona wilkinsona changed the title Order of map property in application yaml not preserved Order of map property in application yaml is no longer preserved May 18, 2020
@wilkinsona wilkinsona added type: regression A regression from a previous release and removed status: waiting-for-triage An issue we've not yet triaged labels May 18, 2020
@wilkinsona wilkinsona added this to the 2.3.1 milestone May 18, 2020
@wilkinsona wilkinsona self-assigned this May 18, 2020
@elitacco
Copy link

elitacco commented May 18, 2020

This issue breaks spring cloud zuul routes configuration.

From Spring Clould Netflix documentation:

If you need your routes to have their order preserved, you need to use a YAML file, as the ordering is lost when using a properties file. The following example shows such a YAML file:

zuul:
 routes:
   users:
     path: /myusers/**
   legacy:
     path: /*

If you were to use a properties file, the legacy path might end up in front of the users path, rendering the users path unreachable.

@dumitrulapteacru-endava

Is somewhere documented that order is preserved?

@wilkinsona
Copy link
Member

@dumitrulapteacru-endava No, I don't believe so. As I said above we've never deliberately guaranteed the ordering. I would avoid relying on it unless you have a good reason to do so.

@dumitrulapteacru-endava

thank you @wilkinsona

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

5 participants