From 7d53c5436420aa93dc2f1749090569ffd8a266fb Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Wed, 7 Feb 2018 13:03:04 -0800 Subject: [PATCH] Fallback to Object.class if ResolvableType can't resolve Fixes gh-11908 --- .../boot/context/properties/bind/Binder.java | 6 ++--- .../properties/bind/CollectionBinder.java | 2 +- .../bind/IndexedElementsBinder.java | 2 +- .../context/properties/bind/MapBinder.java | 8 +++---- .../context/properties/bind/BinderTests.java | 23 +++++++++++++++++++ 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java index 625cfbdbc48..998139e7c9d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java @@ -262,7 +262,7 @@ public class Binder { } private AggregateBinder getAggregateBinder(Bindable target, Context context) { - Class resolvedType = target.getType().resolve(); + Class resolvedType = target.getType().resolve(Object.class); if (Map.class.isAssignableFrom(resolvedType)) { return new MapBinder(context); } @@ -312,7 +312,7 @@ public class Binder { } BeanPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind( name.append(propertyName), propertyTarget, handler, context, false); - Class type = target.getType().resolve(); + Class type = target.getType().resolve(Object.class); if (!allowRecursiveBinding && context.hasBoundBean(type)) { return null; } @@ -330,7 +330,7 @@ public class Binder { // We know there are properties to bind so we can't bypass anything return false; } - Class resolved = target.getType().resolve(); + Class resolved = target.getType().resolve(Object.class); if (resolved.isPrimitive() || NON_BEAN_CLASSES.contains(resolved)) { return true; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java index bb9a889384a..58dbfc354cf 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java @@ -38,7 +38,7 @@ class CollectionBinder extends IndexedElementsBinder> { @Override protected Object bindAggregate(ConfigurationPropertyName name, Bindable target, AggregateElementBinder elementBinder) { - Class collectionType = (target.getValue() == null ? target.getType().resolve() + Class collectionType = (target.getValue() == null ? target.getType().resolve(Object.class) : List.class); ResolvableType aggregateType = forClassWithGenerics(List.class, target.getType().asCollection().getGenerics()); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/IndexedElementsBinder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/IndexedElementsBinder.java index f441239f704..eb260141fd6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/IndexedElementsBinder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/IndexedElementsBinder.java @@ -150,7 +150,7 @@ abstract class IndexedElementsBinder extends AggregateBinder { ResolvableType... generics) { ResolvableType[] resolvedGenerics = new ResolvableType[generics.length]; for (int i = 0; i < generics.length; i++) { - resolvedGenerics[i] = forClassWithGenerics(generics[i].resolve(), + resolvedGenerics[i] = forClassWithGenerics(generics[i].resolve(Object.class), generics[i].getGenerics()); } return ResolvableType.forClassWithGenerics(type, resolvedGenerics); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java index 7e5d083de6b..27808dcca48 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java @@ -54,7 +54,7 @@ class MapBinder extends AggregateBinder> { protected Object bindAggregate(ConfigurationPropertyName name, Bindable target, AggregateElementBinder elementBinder) { Map map = CollectionFactory.createMap( - (target.getValue() == null ? target.getType().resolve() : Map.class), 0); + (target.getValue() == null ? target.getType().resolve(Object.class) : Map.class), 0); Bindable resolvedTarget = resolveTarget(target); boolean hasDescendants = getContext().streamSources().anyMatch((source) -> source .containsDescendantOf(name) == ConfigurationPropertyState.PRESENT); @@ -75,7 +75,7 @@ class MapBinder extends AggregateBinder> { } private Bindable resolveTarget(Bindable target) { - Class type = target.getType().resolve(); + Class type = target.getType().resolve(Object.class); if (Properties.class.isAssignableFrom(type)) { return STRING_STRING_MAP; } @@ -132,7 +132,7 @@ class MapBinder extends AggregateBinder> { private ConfigurationPropertyName getEntryName(ConfigurationPropertySource source, ConfigurationPropertyName name) { - Class resolved = this.valueType.resolve(); + Class resolved = this.valueType.resolve(Object.class); if (Collection.class.isAssignableFrom(resolved) || this.valueType.isArray()) { return chopNameAtNumericIndex(name); } @@ -161,7 +161,7 @@ class MapBinder extends AggregateBinder> { private boolean isScalarValue(ConfigurationPropertySource source, ConfigurationPropertyName name) { - Class resolved = this.valueType.resolve(); + Class resolved = this.valueType.resolve(Object.class); String packageName = ClassUtils.getPackageName(resolved); if (!packageName.startsWith("java.lang") && !resolved.isEnum()) { return false; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/BinderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/BinderTests.java index a648ad25429..6dd0247f670 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/BinderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/BinderTests.java @@ -280,6 +280,15 @@ public class BinderTests { this.binder.bind("foo", target); } + @Test + public void bindToBeanWithUnresolvableGenerics() { + MockConfigurationPropertySource source = new MockConfigurationPropertySource(); + source.put("foo.bar", "hello"); + this.sources.add(source); + Bindable target = Bindable.of(GenericBean.class); + this.binder.bind("foo", target); + } + public static class JavaBean { private String value; @@ -349,4 +358,18 @@ public class BinderTests { } + public static class GenericBean { + + private T bar; + + + public T getBar() { + return this.bar; + } + + public void setBar(T bar) { + this.bar = bar; + } + } + }