Search code examples
javaserializationjung

Is JUNG's DirectedSparseGraph serializable?


Since DirectedSparseGraph implements serializable (javadoc), why can I not create a graph, serialize it to a file, then deserialize it? A "InvalidClassException" is thrown when deserializer.readObject() is called, with the message "no valid constructor".

Looking at the javadoc and source files, it does have a zero-arguments constructor.

Is this a bug in the library? Or am I missing something? What type of constructor is Java expecting?

    DirectedSparseGraph graph = new DirectedSparseGraph();

    FileOutputStream underlyingStream = new FileOutputStream("output/temp.jung");
    ObjectOutputStream serializer = new ObjectOutputStream(underlyingStream);
    serializer.writeObject(graph);
    serializer.close();
    underlyingStream.close();   

    FileInputStream underlyingStream2 = new FileInputStream( "output/temp.jung" ); 
    ObjectInputStream deserializer = new ObjectInputStream( underlyingStream2 );
    DirectedSparseGraph loadedGraph = (DirectedSparseGraph) deserializer.readObject(); //EXCEPTION THROWN HERE
    deserializer.close();
    underlyingStream2.close();

Exception:

Exception in thread "main" java.io.InvalidClassException: edu.uci.ics.jung.graph.DirectedSparseGraph; edu.uci.ics.jung.graph.DirectedSparseGraph; no valid constructor
at java.io.ObjectStreamClass.checkDeserialize(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at gui.GraphViewer.main(GraphViewer.java:39)
Caused by: java.io.InvalidClassException: edu.uci.ics.jung.graph.DirectedSparseGraph; no valid constructor
at java.io.ObjectStreamClass.<init>(Unknown Source)
at java.io.ObjectStreamClass.lookup(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at gui.GraphViewer.main(GraphViewer.java:33)

Solution

  • The only requirement on the constructor for a class that implements Serializable is that the first non-serializable superclass in its inheritence hierarchy must have a no-argument constructor

    Source: http://www.jguru.com/faq/view.jsp?EID=251942

    During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

    Source: http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html