This week, I have been bitten by a surprising behavior of Spring type conversion. Let’s have the following bean and Spring config.
public class Bean { public void setArray(String[] values) { System.out.println("array: " + Arrays.toString(values)); System.out.println(values.length); } public void setList(List<String> values) { System.out.println("list: " + values); System.out.println(values.size()); } }
<bean class="net.javacrumbs.Bean"> <property name="array" value="item1, item2"/> <property name="list" value="item1, item2"/> </bean>
We are trying to inject a String containing comma delimited list of values. The question is whether the String will be automatically converted to list of multiple items in array/list or only one item string will be injected. Both options make sense. What do you think? What will be the length of the array/list? One or two?
The answer is surprising. The array value will be split to two Strings whereas the List will have only one element. The output will be:
array: [item1, item2] 2 list: [item1, item2] 1
It’s an easy error to make but hard one to spot. If you log the values, the output is undistinguishable. If you look at the output above, the values are exactly the same. What’s worse you usually do not have unit tests to test Spring configuration. In my case the bug got as far as production environment. On test environments we have got only one value in the property so the bug went unnoticed. On the production environment we have set a comma separated list of values. And of course, I have expected the array behavior while using list parameter. Silly me.