Home > Back-end >  How to read List of Kotlin Pairs from application.yml
How to read List of Kotlin Pairs from application.yml

Time:10-10

I am working on a Spring Boot project in Kotlin. I would like to read a list of <String,Int> pairs from application.yml file to a mutablelist. The type of the list is as follows.

@Configuration
@EnableAutoConfiguration
@ConfigurationProperties(prefix = "user-parameters")
class UserParameters {
    
    /**
     * Owners of the knapsacks and their capacity.
     */
    var knapsacks = mutableListOf<Pair<String, Int>>()
    
    init {
      ...
    }
}

In the application.yml file, I tried to use the following configuration.

...
user-parameters:
  knapsacks:
   - "[James]": 102
   - "[Mary]": 185

However, this fails with the following error.

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target [Bindable@3a7b2e2 type = java.util.List<kotlin.Pair<java.lang.String, java.lang.Integer>>, value = 'provided', annotations = array<Annotation>[[empty]]] failed:

    Property: user-parameters.knapsacks[0][James]
    Value: 102
    Origin: class path resource [application.yml] - 28:17
    Reason: The elements [user-parameters.knapsacks[0][James],user-parameters.knapsacks[1][Mary]] were left unbound.
    Property: user-parameters.knapsacks[1][Mary]
    Value: 185
    Origin: class path resource [application.yml] - 29:16
    Reason: The elements [user-parameters.knapsacks[0][James],user-parameters.knapsacks[1][Mary]] were left unbound.

Action:

Update your application's configuration

The code works if I change the type to Map<String, Int> but I need Pair<String, Int> due to implementation details.

I have also tried the following annotations but to no avail.

...
user-parameters:
  knapsacks:
   - "[James]": 102
     "[Mary]": 185
...
user-parameters:
  knapsacks:
   "[James]": 102
   "[Mary]": 185
...
user-parameters:
  knapsacks:
   - { "[James]": 102 }
   - { "[Mary]": 185 }

How can I achieve reading pairs of String,Int to a mutable list from application.yml?

CodePudding user response:

As far as I know Spring Boot does not support Pair of the kotlin-stdlib out-of-the-box.

Spring cannot know how to parse arbitrary classes in arbitrary ways. Spring does support classes following Bean conventions however.

Thus, there are at least three solutions to your problem:

  1. Simply parse as Map as outlined in the question and convert your Map<String, Int> to a List<Pair<String, Int>>, e.g. by calling map.toList(), see the official documentation.

You may provide a custom getter for the list.

val knapsacksList: List<Pair<String, Int>>
   get() { knapsacks.toList() }
  1. Adjust your application.yml to conform to the form of Pair. A Pair is a simple data class having two values being first and second. If you provide these in the .yml-file, Spring can parse them accordingly.

Something along the lines of the following may work.

...
user-parameters:
  knapsacks:
   - first: "James"
     second: 102"
   - first: "Mary"
     second: 185
  1. Provide a custom Converter for your use case. There are resources online on how to achieve this, for example from baeldung.com.

Note that I've written this answer on my phone, thus I couldn't test any of this and there might be minor typos.

  • Related