2

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)
Crashthatch
  • 1,283
  • 2
  • 13
  • 20
  • Do you intend to save its vertices, persist them in a file and later loads them from that file to their last state? If yes, check `PersistentLayoutDemo.java` in `jung-samples-2.0.1.jar` (with its `jung-samples-2.0.1-sources.jar`). `PersistentLayoutImpl.persist()` method implements `PersistentLayout.persist()` interface method and uses a serialized `Point` class to save the vertex points. – ee. Mar 28 '12 at 01:12

2 Answers2

1

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

Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • So if the class it extends doesn't have a no-argument constructor, it's impossible to serialize it? In that case, why bother implementing serializable? Is this a mistake in the library? – Crashthatch Mar 28 '12 at 00:06
  • 2
    It may have been serializable at a time when the superclass had the required constructor. See also [*Item 74: Implement Serializable judiciously*](http://java.sun.com/docs/books/effective/). – trashgod Mar 28 '12 at 03:10
0

I serialize DirectedSparseGraph using the XStream library. You serialize and unserialize objects with 2 lines of code, even if the objects do not implement Serializable. So this is particuarly useful when serializing third-party objects, which you cannot modify to make them Serializable.

Once you try this, you never come back to native Java serialization. The only problem is that XStream serializes to XML, so if you have strict performance requirements, it is not the best choice.

Alphaaa
  • 4,206
  • 8
  • 34
  • 43