diff --git a/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java b/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java index 96aa7885b3..b234e9e64a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java +++ b/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/CollectionBinder.java @@ -51,9 +51,26 @@ class CollectionBinder extends IndexedElementsBinder> { @Override protected Collection merge(Collection existing, Collection additional) { - existing.clear(); - existing.addAll(additional); - return existing; + try { + existing.clear(); + existing.addAll(additional); + return existing; + } + catch (UnsupportedOperationException ex) { + return createNewCollection(additional); + } + } + + @SuppressWarnings("unchecked") + private Collection createNewCollection(Collection additional) { + try { + Collection merged = additional.getClass().newInstance(); + merged.addAll(additional); + return merged; + } + catch (Exception e) { + throw new IllegalStateException("Adding bound values to collection failed."); + } } } diff --git a/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/CollectionBinderTests.java b/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/CollectionBinderTests.java index a64c3149ef..ee48c20e81 100644 --- a/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/CollectionBinderTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/CollectionBinderTests.java @@ -17,6 +17,7 @@ package org.springframework.boot.context.properties.bind; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -289,4 +290,15 @@ public class CollectionBinderTests { List values = result.stream().map(JavaBean::getValue).collect(Collectors.toList()); assertThat(values).containsExactly("a", "b", "c"); } + + @Test + public void bindToImmutableCollectionShouldReturnPopulatedCollection() throws Exception { + MockConfigurationPropertySource source = new MockConfigurationPropertySource(); + source.put("foo.values", "a,b,c"); + this.sources.add(source); + Set result = this.binder.bind("foo.values", + STRING_SET.withExistingValue(Collections.emptySet())).get(); + assertThat(result).hasSize(3); + } + }