Details
-
Type: Bug
-
Status: Closed
-
Priority: Critical
-
Resolution: Fixed
-
Affects Version/s: 1.3.1
-
Fix Version/s: 1.4
-
Component/s: Converters
-
Labels:None
-
JDK version and platform:Sun 6u12
Description
Some of our objects cannot be deserialized as a duplicate @class field is generated.
In the following code we get the error
{"object-array":{"jsonfails.JSONManualTest_-A":[{"yesNo":[{"@class":"jsonfails.JSONManualTest$YesNo","$":"NO"},{"@class":"jsonfails.JSONManualTest$YesNo","$":"NO"}],"b":{}}]},"jsonfails.JSONManualTest_-A":{"@reference":"..\/jsonfails.JSONManualTest_-A"}} Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: yesNo ---- Debugging information ---- duplicate-field : yesNo class : [Ljava.lang.Object; required-type : jsonfails.JSONManualTest$A path : /object-array/jsonfails.JSONManualTest$A/yesNo[2] line number : -1 ------------------------------- at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$SeenFields.add(AbstractReflectionConverter.java:322) at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:234) at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:162) at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82) 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.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71) at com.thoughtworks.xstream.converters.collections.ArrayConverter.unmarshal(ArrayConverter.java:55) at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:82) 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 jsonfails.JSONManualTest.main(JSONManualTest.java:43)
Using the following code
public class JSONManualTest { enum YesNo { YES { @Override public String toString() { return "Yes!!"; }}, NO { @Override public String toString() { return "Oh no."; }} } public static class A { Object yesNo; B b; } public static class B { Object yesNo; // if this field is called text, there is no duplicate @class. } public static void main(String... args) { XStream xs = new XStream(new JettisonMappedXmlDriver()); A a = new A(); a.yesNo = YesNo.NO; a.b = new B(); a.b.yesNo = YesNo.NO; Object[] o = { a, a}; String asJSON = xs.toXML(o); System.out.println(asJSON); Object a2 = xs.fromXML(asJSON); String asJSON2 = xs.toXML(a2); if (!asJSON.equals(asJSON2)) throw new AssertionError("Expected \"" + asJSON + "\" to equals \"" + asJSON2 + "\""); } }
Hi Peter,
there's unfortunately not much XStream can do about, since it is Jettison's heuristic that's failing. The presence of a second "yesNo" element in sequence (compare the XML output), triggers Jettison's array mode (as you can see by the structure of the JSON output above) and from there on it goes downhill, since your Java objects build no array :-/
I am currently not aware of a configuration possibility in Jettison's MappedXMLOutputFactory to prevent the array heuristic in such a case.