I'd like to have spring load some properties on startup and convert them into the proper types.
application.yml:
base:
security:
scopes:
- name: read
descripton: read some nice things
- name: write
description: write some nice things
authorities:
- name: ROLE_ADMIN
scopes:
- read
- write
- name: ROLE_USER
scopes:
- read
To load these properties into types I used the following @ConfigurationProperties: BaseProperties.java
@Setter
@Getter
@Configuration
@ConfigurationProperties(prefix="base.security")
public class BaseProperties {
private Set<ScopeProperty> scopes = new HashSet<>();
private Set<AuthorityProperty> authorities = new HashSet<>();
@Getter
@Setter
public class AuthorityProperty {
private String name;
private List<String> scopes;
}
@Getter
@Setter
public class ScopeProperty {
private String name;
private String description;
}
}
Everything I get is a BindException as follows:
Caused by: org.springframework.boot.context.properties.bind.UnboundConfigurationPropertiesException: The elements [base.security.authorities[0].name,base.security.authorities[0].scopes[0],base.security.authorities[0].scopes[1],base.security.authorities[1].name,base.security.authorities[1].scopes[0]] were left unbound.
at org.springframework.boot.context.properties.bind.IndexedElementsBinder.assertNoUnboundChildren(IndexedElementsBinder.java:136)
at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:113)
at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:86)
at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:71)
at org.springframework.boot.context.properties.bind.CollectionBinder.bindAggregate(CollectionBinder.java:49)
at org.springframework.boot.context.properties.bind.AggregateBinder.bind(AggregateBinder.java:56)
at org.springframework.boot.context.properties.bind.Binder.lambda$bindAggregate$2(Binder.java:293)
at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:429)
at org.springframework.boot.context.properties.bind.Binder$Context.access$100(Binder.java:372)
at org.springframework.boot.context.properties.bind.Binder.bindAggregate(Binder.java:293)
at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:254)
at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:214)
solution:
Either mark the classes as static or create them as seperate classes:
@Getter
@Setter
public static class AuthorityProperty {
private String name;
private List<String> scopes;
}
@Getter
@Setter
public static class ScopeProperty {
private String name;
private String description;
}
Your classes are inner classes which require an instance of outer class BaseProperties to be constructed, which is not supported by Spring Properties.
You can mark your classes with keyword static
which is supposed to work
@Getter
@Setter
public static class AuthorityProperty {
private String name;
private List<String> scopes;
}