Details
-
Type: Bug
-
Status: Closed
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 1.2
-
Component/s: None
-
Labels:None
-
JDK version and platform:JDK 5.0_06 for windows
Description
Rules for serialization say that if at some point in superclass hierarchy class is not serializable, it's default constructor should be called. XStream is not doing that. Below I'm attaching a small testcase, but it is a real problem in case of THashMap from troovy - default load factor is not set to 0.75 as in default constructor (and it is not transferred because trovy decided to not serialize it), which leads to memory expanding on every object read, leading finally to OutOfMemoryException.
import java.io.*;
import com.thoughtworks.xstream.XStream;
public class SerializeTest {
static class A {
public int x;
public A()
{ x = 5; }}
static class B extends A implements Serializable {
public int y;
public B()
{ y = 10; }private void writeObject(ObjectOutputStream stream) throws IOException
{ stream.defaultWriteObject(); }private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException
{ stream.defaultReadObject(); }}
public static void main(String[] argv) throws Exception
{ B b = new B(); B retrieved; XStream stream = new XStream(); String str = stream.toXML(b); // System.out.println(str); retrieved = (B) stream.fromXML(str); System.out.println("XStream.x=" + retrieved.x); System.out.println("XStream.y=" + retrieved.y); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(b); oos.close(); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); retrieved = (B) ois.readObject(); System.out.println("Java.x=" + retrieved.x); System.out.println("Java.y=" + retrieved.y); }}
XStream will now save the fields of unserializable parents also in the XML stream, so it can initialize these fields unmarshalling the object.