Closed
Description
There are cases that configuration property binding does not work when integrating 3rd party configuration class and it deploy to the application server as war file(= When JndiPropertySource is enabled).
Versions
- 2.2.0.RELEASE(2.2.0.M5+) ※2.2.0.M4 work fine
Details
For example, following properties class does not work. (As actually, MyBatis's configuration class matches this pattern...)
package com.example;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
@ConfigurationProperties(prefix = "my")
public class MyProperties {
private String name;
@NestedConfigurationProperty
private ThirdPartyConfiguration configuration; // ### Third party class
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setConfiguration(ThirdPartyConfiguration configuration) {
this.configuration = configuration;
}
public ThirdPartyConfiguration getConfiguration() {
return configuration;
}
}
package com.example;
public class ThirdPartyConfiguration {
private String encoding;
private boolean enabled;
private final List<ResultMap> resultMaps = new ArrayList<>(); // ### Collection
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public String getEncoding() {
return encoding;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isEnabled() {
return enabled;
}
public Collection<ResultMap> getResultMaps() {
return resultMaps;
}
public void addResultMap(ResultMap rm) {
resultMaps.add(rm);
}
}
package com.example;
public class ResultMap {
private String name;
private String option;
private ResultMap() { // ### Define private (If define public, this issue does not occurred)
}
public String getName() {
return name;
}
public String getOption() {
return option;
}
public static class Builder { // ### Builder class
private final ResultMap resultMap;
public Builder(String name) {
resultMap = new ResultMap();
resultMap.name = name;
}
public Builder option(String option) {
resultMap.option = option;
return this;
}
public ResultMap build() {
return resultMap;
}
}
}
StackTrace
...
[INFO] [talledLocalContainer] Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my.configuration.result-maps[0]' to com.example.ResultMap
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:337)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:297)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$null$1(Binder.java:385)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withSource(Binder.java:519)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.access$1000(Binder.java:486)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$bindAggregate$2(Binder.java:386)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:106)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:86)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.IndexedElementsBinder.bindIndexed(IndexedElementsBinder.java:71)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.CollectionBinder.bindAggregate(CollectionBinder.java:49)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.AggregateBinder.bind(AggregateBinder.java:56)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$bindAggregate$3(Binder.java:388)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:543)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.access$200(Binder.java:486)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindAggregate(Binder.java:388)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:349)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:293)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:421)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:88)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:77)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:54)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:425)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:543)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:529)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.access$500(Binder.java:486)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:423)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:364)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:293)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$4(Binder.java:421)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:88)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:77)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.JavaBeanBinder.bind(JavaBeanBinder.java:54)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:425)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:543)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:529)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.access$500(Binder.java:486)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:423)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:364)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:293)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:281)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:211)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:198)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.ConfigurationPropertiesBinder.bind(ConfigurationPropertiesBinder.java:89)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.bind(ConfigurationPropertiesBindingPostProcessor.java:107)
[INFO] [talledLocalContainer] ... 60 more
[INFO] [talledLocalContainer] Caused by: java.lang.IllegalStateException: Failed to extract parameter names for com.example.ResultMap(com.example.ResultMap$1)
[INFO] [talledLocalContainer] at org.springframework.util.Assert.state(Assert.java:94)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.ValueObjectBinder$DefaultValueObject.parseConstructorParameters(ValueObjectBinder.java:178)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.ValueObjectBinder$DefaultValueObject.<init>(ValueObjectBinder.java:173)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.ValueObjectBinder$DefaultValueObject.get(ValueObjectBinder.java:218)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.ValueObjectBinder$DefaultValueObject.get(ValueObjectBinder.java:206)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.ValueObjectBinder$ValueObject.get(ValueObjectBinder.java:112)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.ValueObjectBinder.bind(ValueObjectBinder.java:51)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.lambda$bindDataObject$5(Binder.java:425)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:543)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.withDataObject(Binder.java:529)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder$Context.access$500(Binder.java:486)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindDataObject(Binder.java:423)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:364)
[INFO] [talledLocalContainer] at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:293)
Related Issue
Reproduce project
How to reproduce
$ ./mvnw package corgo:run