|
A nested class cannot be serialized by XStream 1.4.5 in Oracle JDK8 Early Access Build b108.
Code sample:
public class OrderRetainingMapTest {
private static class Class1 implements Serializable {
private final int fValue1;
private Class1(int value1)
{
fValue1 = value1;
}
@Override
public String toString()
{
return String.valueOf(fValue1);
}
}
private static class Class2 extends Class1 {
private final int fValue2;
protected Class2(int value1, int value2)
{
super(value1);
fValue2 = value2;
}
@Override
public String toString()
{
return super.toString() + "/" + String.valueOf(fValue2);
}
}
private static final class Class3 extends Class2 {
private final int fValue3;
private Class3(int value1, int value2, int value3)
{
super(value1, value2);
fValue3 = value3;
}
@Override
public String toString()
{
return super.toString() + "/" + String.valueOf(fValue3);
}
}
@Test
public void testXStreamClass3ToXml()
{
XStream xstream = new XStream(new DomDriver());
xstream.toXML(new Class3(0, 0, 0));
}
}
causes
java.lang.ArrayIndexOutOfBoundsException: -1
at com.thoughtworks.xstream.core.util.OrderRetainingMap.entrySet(OrderRetainingMap.java:77)
at java.util.HashMap.putMapEntries(HashMap.java:511)
at java.util.HashMap.putAll(HashMap.java:784)
at com.thoughtworks.xstream.core.util.OrderRetainingMap.<init>(OrderRetainingMap.java:36)
at com.thoughtworks.xstream.converters.reflection.FieldDictionary.buildMap(FieldDictionary.java:135)
at com.thoughtworks.xstream.converters.reflection.FieldDictionary.fieldsFor(FieldDictionary.java:76)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:127)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:83)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:73)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:993)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:982)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:955)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:942)
at com.thoughtworks.xstream.OrderRetainingMapTest.testXStreamClass3ToXml(OrderRetainingMapTest.java:69)
It seems that the HashMap#putAll(Map) call in the constructor of OrderRetainingMap with map parameter
public class OrderRetainingMap extends HashMap {
...
public OrderRetainingMap(Map m)
{
super();
putAll(m);
}
...
}
is no more compatible with the HashMap implementation.
Potential fixes:
1) define putAll(Map) in OrderRetainingMap
public void putAll(Map m) {
for (Entry e : m.entrySet())
{
put(e.getKey(), e.getValue());
}
}
or
2) subclass LinkedHashMap
public class OrderRetainingMap extends LinkedHashMap {
public OrderRetainingMap()
{
super();
}
public OrderRetainingMap(Map m)
{
super(m);
}
}
or
3) use LinkedHashMap instead of OrderRetainingMap, drop OrderRetainingMap
The same problem seems to occur with IBM SDK, see http://jira.codehaus.org/browse/XSTR-739.
|