Details
-
Type: Bug
-
Status: Closed
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 1.1.1
-
Component/s: None
-
Labels:None
-
JDK version and platform:Sun 1.4.2_06 for Windows
Description
I have the following issue.
I am serializing an object that implements the writeReplace method. The write replace method returns an object of a different type to the original.
The replacement type implements the readResolve method which returns an object of the original type.
The xml generated by xstream specifies an object of the original type but contains the fields of the replacement type.
This causes a problem when unmashalling the xml as it creates an object of the orriginal type and tries to assign the values of the replacement type to it.
Here is an example:
import com.thoughtworks.xstream.XStream;
import java.io.Serializable;
public class Streamtest
{
public static void main( String argv[])
public static class TestClass implements Serializable{
int testClassValue = 23;
private Object writeReplace()
{ return new TestClassReplacement(); }}
public static class TestClassReplacement implements Serializable {
String replacementTestClassValue = "Replaced Value";
private Object readResolve()
{ return new TestClass(); } }
}
executing this generates the following output:
<Streamtest-TestClass>
<replacementTestClassValue>Replaced Value</replacementTestClassValue>
</Streamtest-TestClass>
com.thoughtworks.xstream.converters.ConversionException: replacementTestClassValue : replacementTestClassValue
---- Debugging information ----
required-type : Streamtest$TestClass
cause-message : replacementTestClassValue : replacementTestClassValue
class : Streamtest$TestClass
message : replacementTestClassValue : replacementTestClassValue
line number : 2
path : /Streamtest-TestClass/replacementTestClassValue
cause-exception : com.thoughtworks.xstream.alias.CannotResolveClassException
-------------------------------
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:46)
at com.thoughtworks.xstream.core.ReferenceByXPathUnmarshaller.convertAnother(ReferenceByXPathUnmarshaller.java:37)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:96)
at com.thoughtworks.xstream.core.ReferenceByXPathMarshallingStrategy.unmarshal(ReferenceByXPathMarshallingStrategy.java:12)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:286)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:274)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:242)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:233)
at Streamtest.main(Streamtest.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78)
Caused by: com.thoughtworks.xstream.alias.CannotResolveClassException: replacementTestClassValue : replacementTestClassValue
at com.thoughtworks.xstream.core.DefaultClassMapper.lookupType(DefaultClassMapper.java:223)
at com.thoughtworks.xstream.converters.reflection.ReflectionConverter.determineType(ReflectionConverter.java:178)
at com.thoughtworks.xstream.converters.reflection.ReflectionConverter.unmarshal(ReflectionConverter.java:104)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:39)
... 13 more
Exception in thread "main"
As I understand it should be the replacement object that is actually serialized and hence the xml generated should be:
<Streamtest-TestClassReplacement>
<replacementTestClassValue>Replaced Value</replacementTestClassValue>
</Streamtest-TestClassReplacement>
Which is unmartialled correctly to a Streamtest.TestClass.
Thanks and keep up the good work,
Regards Francis
Fixed.... grab the latest snapshot to try it out:
http://dist.codehaus.org/xstream/jars/xstream-SNAPSHOT.jar
thanks
-Joe