Issue 1:
Sam Brannen opened SPR-6523 and commented

Section C.2.2.4 util:list/ of the reference manual states:

Finally, you can also control the merging behavior using the 'merge' attribute of the util:list/ element; collection merging is described in more detail in the section called "Collection merging".

This is, however, not true. In contrast to the standard support for collections (i.e., array, list, set, map) in the beans namespace, the util namespace does not support the merge attribute for collections.

Is this an oversight in the documentation or missing functionality in the util namespace support?

On a related note (perhaps worthy of its own JIRA issue), given the following application context configuration and JUnit test class...

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">

<bean id="listHolderParent" class="com.example.MergedListTests$ListHolder"
abstract="true">
<property name="list">
<list>
<value>red</value>
<value>green</value>
<value>blue</value>
</list>
</property>
</bean>

<bean id="listHolder" parent="listHolderParent">
<property name="list">
<list merge="true">
<value>cyan</value>
<value>magenta</value>
<value>yellow</value>
<value>black</value>
</list>
</property>
</bean>

</beans>

package com.example;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MergedListTests {

@Test
public void mergedList() {
ApplicationContext appCtx = new ClassPathXmlApplicationContext(
"/com/example/MergedListTests-context.xml");
ListHolder listHolder = appCtx.getBean("listHolder", ListHolder.class);
assertNotNull(listHolder);
assertEquals(7, listHolder.getList().size());
}

public static class ListHolder {

private List<String> list;

public List<String> getList() {
return this.list;
}

public void setList(List<String> list) {
this.list = list;
}
}
}

... changing the definition in listHolderParent to util:list results in the following exception:

java.lang.IllegalArgumentException: Cannot merge with object of type [class org.springframework.beans.factory.config.BeanDefinitionHolder]

at org.springframework.beans.factory.support.ManagedList.merge(ManagedList.java:98)

at org.springframework.beans.factory.support.ManagedList.merge(ManagedList.java:1)

at org.springframework.beans.MutablePropertyValues.mergeIfRequired(MutablePropertyValues.java:221)

at org.springframework.beans.MutablePropertyValues.addPropertyValue(MutablePropertyValues.java:169)

at org.springframework.beans.MutablePropertyValues.addPropertyValues(MutablePropertyValues.java:138)

at org.springframework.beans.factory.support.AbstractBeanDefinition.overrideFrom(AbstractBeanDefinition.java:300)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1114)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedBeanDefinition(AbstractBeanFactory.java:1054)

at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1040)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:294)

at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:578)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:398)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)

at com.example.MergedListTests.mergedList(MergedListTests.java:17)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

...

Issue Links:

#10561 Merge multiple lists/maps/sets that share the same id into a single map/list ("Cloned from")

#9658 support cascading merge operation ("is duplicated by")

#13477 Add MapCombiningFactoryBean ("is duplicated by")

#7575 Support easier merge/concatenation of lists ("is duplicated by")

#14186 Respect 'merge' attribute of and elements in conjunction with nested property paths

#9437 Merge of util:map does not work

#6201 Support for Collection Merging in Parent/Child Bean Definitions

#9872 Re-allow merge of util:map list, set, ... based on the same bean ID

Referenced from: commits a827ab8

16 votes, 18 watchers

Issue 2:
Thomas Timbul opened SPR-5199 and commented

For the sake of clarity/modularisation in my XML I am trying to separate out certain service definitions into separate files. It would be nice to see the re-emergence of 'merge' on the util: collection definitions in a way that definitions with the same ID are merged.

For example (hope this submits in a readable way):

[services.xml]

<util:map id="serviceMap" merge="true" />

<bean id="serviceProvider">

<property name="serviceMap" ref="serviceMap" />

</bean>

[service1.xml]

<util:map id="serviceMap" merge="true">

<entry key="S1" ref="service1" />

</util:map>

<bean id="service1" ..... />

[service2.xml]

<util:map id="serviceMap" merge="true">

<entry key="S2" ref="service2" />

</util:map>

<bean id="service2" ..... />

There are probably workarounds for this, but for the moment I would be forced to have the serviceMap defined completely in a single place.

Issue Links:

#11189 Introduce 'merge' attribute for util namespace collection elements

3 votes, 2 watchers