Browse Source

Fix error message when constructor binding fails to create bean

The configuration property is always cleared before bean instantiation
because the problem with bean instantiation might not necessarily be the
last bound property.

Fixes gh-18704
pull/18752/head
Madhura Bhave 6 years ago
parent
commit
dec6ee20d4
  1. 2
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java
  2. 1
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/ValueObjectBinder.java
  3. 38
      spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/ValueObjectBinderTests.java

2
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java

@ -551,7 +551,7 @@ public class Binder { @@ -551,7 +551,7 @@ public class Binder {
this.configurationProperty = configurationProperty;
}
private void clearConfigurationProperty() {
void clearConfigurationProperty() {
this.configurationProperty = null;
}

1
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/ValueObjectBinder.java

@ -61,6 +61,7 @@ class ValueObjectBinder implements DataObjectBinder { @@ -61,6 +61,7 @@ class ValueObjectBinder implements DataObjectBinder {
arg = (arg != null) ? arg : parameter.getDefaultValue(context.getConverter());
args.add(arg);
}
context.clearConfigurationProperty();
return bound ? valueObject.instantiate(args) : null;
}

38
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/ValueObjectBinderTests.java

@ -21,6 +21,7 @@ import java.util.ArrayList; @@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import com.atomikos.util.Assert;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
@ -29,6 +30,7 @@ import org.springframework.boot.context.properties.source.MockConfigurationPrope @@ -29,6 +30,7 @@ import org.springframework.boot.context.properties.source.MockConfigurationPrope
import org.springframework.format.annotation.DateTimeFormat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link ValueObjectBinder}.
@ -220,6 +222,20 @@ class ValueObjectBinderTests { @@ -220,6 +222,20 @@ class ValueObjectBinderTests {
assertThat(bean.getDate().toString()).isEqualTo("2019-05-10");
}
@Test
void bindWhenAllPropertiesBoundShouldClearConfigurationProperty() { // gh-18704
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
source.put("foo.bar", "hello");
this.sources.add(source);
Bindable<ValidatingConstructorBean> target = Bindable.of(ValidatingConstructorBean.class);
assertThatExceptionOfType(BindException.class).isThrownBy(() -> this.binder.bind("foo", target))
.satisfies(this::noConfigurationProperty);
}
private void noConfigurationProperty(BindException ex) {
assertThat(ex.getProperty()).isNull();
}
static class ExampleValueBean {
private final int intValue;
@ -413,4 +429,26 @@ class ValueObjectBinderTests { @@ -413,4 +429,26 @@ class ValueObjectBinderTests {
}
static class ValidatingConstructorBean {
private final String foo;
private final String bar;
ValidatingConstructorBean(String foo, String bar) {
Assert.notNull("Foo must not be null", foo);
this.foo = foo;
this.bar = bar;
}
String getFoo() {
return this.foo;
}
String getBar() {
return this.bar;
}
}
}

Loading…
Cancel
Save