Hi XStream team,
First of all 1000000 thanks for the excellent product.
I have been using XStream since 2007 and it has become a heart of many
my projects.
Few days ago i mentioned that in some special cases calls of
XStream.addImpliciteCollection
(
Class definedIn,
String collectionFieldName,
Class itemType
)
delivered unexpected results.
Assume we have the following class hierarchy
public class Parent
extends Object
{
public ArrayList<I> parentCollection = null;
}
public class Child1
extends Parent
{
public ArrayList<I> child1Collection = null;
}
public class Child2
extends Parent
{
public ArrayList<I> child2Collection = null;
}
and the following XStream setup:
private final static XStream setupSerializer()
{
final XStream s = new XStream
(
new PureJavaReflectionProvider(), new DomDriver()
);
// Parent
s.alias("parent", Parent.class);
s.addImplicitCollection(Parent.class, "parentCollection",
I.class);
// Child1
s.alias("child1", Child1.class);
s.addImplicitCollection(Child1.class, "child1Collection",
I.class);
// Child2
s.alias("child2", Child2.class);
s.addImplicitCollection(Child2.class, "child2Collection",
I.class);
// IImpl1
s.alias("i1", IImpl1.class);
// IImpl2
s.alias("i2", IImpl2.class);
return s;
}
then an attempt to deserialize the string
"<child1><i1/><i2/><i1/></child1>"
leads to the following exception:
com.thoughtworks.xstream.converters.ConversionException: No such
field com.vn.xml.serialization.Child1.child2Collection : No such
field com.vn.xml.serialization.Child1.child2Collection
---- Debugging information ----
message : No such field
com.vn.xml.serialization.Child1.child2Collection
cause-exception :
com.thoughtworks.xstream.converters.reflection.ObjectAccessException
cause-message : No such field
com.vn.xml.serialization.Child1.child2Collection
class : com.vn.xml.serialization.Child1
required-type : com.vn.xml.serialization.Child1
path : /child1/i1
-------------------------------
at
com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:89)
at
com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:63)
at
com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:76)
at
com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:60)
at
com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:137)
at
com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:33)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:923)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:909)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:853)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:845)
at
com.vn.xml.serialization.ImpliciteCollectionsTest.testImpliciteCollection(ImpliciteCollectionsTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at
org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by:
com.thoughtworks.xstream.converters.reflection.ObjectAccessException:
No such field com.vn.xml.serialization.Child1.child2Collection
at
com.thoughtworks.xstream.converters.reflection.FieldDictionary.field(FieldDictionary.java:94)
at
com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.getFieldType(PureJavaReflectionProvider.java:151)
at
com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.writeValueToImplicitCollection(AbstractReflectionConverter.java:264)
at
com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:236)
at
com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:162)
at
com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82)
... 26 more
Changing setup sequence to Child1/Child2/Parent solves the problem.
Simple JUnit is attached to mail.
Thank you in advance and hope to here you soon.
import java.util.ArrayList;
import junit.framework.TestCase;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
import com.thoughtworks.xstream.io.xml.DomDriver;
public final class ImpliciteCollectionsTest
extends TestCase
{
public interface I
{
public String getId();
}
public static class Parent
extends Object
{
public ArrayList<I> parentCollection = null;
}
public static class Child1
extends Parent
{
public ArrayList<I> child1Collection = null;
}
public static class Child2
extends Parent
{
public ArrayList<I> child2Collection = null;
}
public final static class IImpl1
extends Object
implements I
{
@Override
public final String getId()
{
return "1";
}
}
public final static class IImpl2
extends Object
implements I
{
@Override
public final String getId()
{
return "2";
}
}
public final void testImpliciteCollection()
{
final XStream s = setupSerializer();
final Child2 child2 = (Child2)s.fromXML
(
"<child2><i1/><i2/><i1/></child2>"
);
assertNull("parentCollection", child2.parentCollection);
assertNotNull("child2Collection", child2.child2Collection);
assertEquals("child2Collection.size()", 3, child2.child2Collection.size());
final Child1 child1 = (Child1)s.fromXML
(
"<child1><i1/><i2/><i1/></child1>"
);
assertNull("parentCollection", child1.parentCollection);
assertNotNull("child2Collection", child1.child1Collection);
assertEquals("child2Collection.size()", 3, child1.child1Collection.size());
}
private final static XStream setupSerializer()
{
final XStream s = new XStream
(
new PureJavaReflectionProvider(), new DomDriver()
);
// Parent
s.alias("parent", Parent.class);
s.addImplicitCollection(Parent.class, "parentCollection", I.class);
// Child1
s.alias("child1", Child1.class);
s.addImplicitCollection(Child1.class, "child1Collection", I.class);
// Child2
s.alias("child2", Child2.class);
s.addImplicitCollection(Child2.class, "child2Collection", I.class);
// IImpl1
s.alias("i1", IImpl1.class);
// IImpl2
s.alias("i2", IImpl2.class);
return s;
}
}
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email