views:

187

answers:

3

I have a node tree built out of Node objects. They are more complex than the code I am showing but only have primitive or Serializable instance members.

Assuming each Node can have up to 10 children the code looks a bit like so.

public class Node implements Serializable{

    private static final long serialVersionUID = -848926218090221003L;

private Node _parent;
private boolean _hasParent;
private Node[] _children;
private int _childCount = 0;

public Node(Node parent){

 _children = new Node[10];
 _parent = parent;
 _hasParent = (parent != null);
}


    ...

    //Various accessors etc

}

Now this tree is quite expensive to build but once it is done I write it to a file:

ObjectOutputStream serializedOuput = new ObjectOutputStream(new FileOutputStream(cacheFile));
serializedOuput.writeObject(tree);
serializedOuput.close();

When I am done caching the tree I make some irreversable changes to like trimming off unneeded branches.

Then when I next need a base tree to work from I create a new tree object by reading in my serialized file.

The problem...

Creating the tree from the file seems to simply create a new object that points to the old one. In other words the modifications made after writing to file have also been made to the new tree.

If I restart the app and try reading in the serialized file it returns null.

So I seem to be serializing object references rather than the object itself, any ideas where I am going wrong?

A: 

perhaps change the seri. id

Tobiask
+2  A: 

Works for me, GNU/Linux with gij 4.3.2.

Make sure all of your fields in the Node class are serializable as well.

This is the code I tried (should be equivalent to yours):

import java.io.*;

public class TestCase {
    public static void main(String[] args) {
        try {
            if (args.length > 0 && args[0].equals("read")) {
                ObjectInputStream ois = new ObjectInputStream(
                        new FileInputStream("File.log")
                    );
                Node root = (Node) ois.readObject();
                ois.close();

                System.out.println("Root value: " + root.getValue());
                for(Node n : root.children())
                    System.out.println("Child: " + n.getValue());

                return;
            }

            Node root = new Node(null, "First");
            root.add(
                    new Node(root, "Second.Child.1"),
                    new Node(root, "Second.Child.2")
                );

            ObjectOutputStream oos = new ObjectOutputStream(
                    new FileOutputStream("File.log")
                );
            oos.writeObject(root);
            oos.close();
        } catch(Exception e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
        }
    }
}

class Node implements Serializable {
    private static final long serialVersionUID = 2304728943L;
    private Node _parent;
    private Node[] _children;
    private String _value;

    public Node(Node parent, String value) {
        this._parent = parent;
        this._value = value;
        this._children = new Node[2];
    }
    public void add(Node child, Node child2) {
        this._children[0] = child;
        this._children[1] = child2;
    }
    public String getValue() {
        return this._value;
    }
    public Node[] children() {
        return this._children;
    }
    public Node parent() {
        return this._parent;
    }
}
Björn
That makes me think it is something else that is causing this to happen. I'll have to dig deeper thanks.
Adrian Hope-Bailie
+1  A: 

One thing you may be doing is serialising the object, changing it and then serialising it to the same stream. You will need to reset the stream, otherwise the logic for handling non-hierarchical structures will ignore your changes. Other possibilities are statics/singleton or strange use of readResolve.

Tom Hawtin - tackline