views:

1508

answers:

8

I am wondering whether it is safe to mix jdk 1.5 and 1.6 (Java 6) object serialization (biderctional communication). I searched for an explicit statement from sun concerning this question but did not succeed. So, besides the technical feasability I am searching for an "official" statement concerning the problem.

+1  A: 

After testing with a serialized object written to a file using the ObjectOutputStream in a Java 1.5 program, then running a read with a ObjectInputStream in a Java 1.6 program I can say this worked without any issue.

GavinCattell
+6  A: 

The serialization mechanism itself has not changed. For individual classes it will depend on the specific class. If a class has a serialVersionUID field, this is supposed to indicate serialization compatiblity.

Something like:

private static final long serialVersionUID = 8683452581122892189L;

If it is unchanged, the serialized versions are compatible. For JDK classes this is guaranteed, but of course it is always possible to forget to update the serialVersionUID after making a breaking change.

When JDK classes are not guaranteed to be compatible, this is usually mentioned in the Javadoc.

Warning: Serialized objects of this class will not be compatible with future Swing releases

Tom
+2  A: 

I would quickly add that it is possible to change the class but forget to change the serialVersionUID. So it is incorrect that "If the class defines a serialVersionUID, and this does not change, the class is guaranteed to be compatible." Rather, having the same serialVersionUID is the way an API promises backward compatibility.

Alan
I was assuming the question is about jdk classes, and that their serialVersionUIDs are correct...
Tom
Fair enough: if your JDK upgrade messes up Serializable, the clients of the your big boy JDK (i.e. Sun, BEA, IBM, etc.) should scream bloody murder (and I have). Admittedly the question wasn't clear whether it was only about JDK classes.
Alan
A: 

Unless otherwise stated, this should be part of binary compatibility. Swing classes are explicitly not compatible between versions. If you find a problem with other classes, report a bug on bugs.sun.com.

Tom Hawtin - tackline
Binary compatiblity is about the public and protected interface, while serialization compatibility deals with usually private fields. Are you sure one implies the other ?
Tom
Technically it is not binary compatibility as defined by Chapter 13 of the JLS. However binary compatibility with respect to serialisation is required between Java versions, unless otherwise specified. If you find a problem, report a bug.
Tom Hawtin - tackline
+1  A: 

Have you read the Java Object Serialization Specification? There is a topic on versioning. There is also an article for class implementers: Discover the secrets of the Java Serialization API. Each release of Java is accompanied by compatibility notes.

From the Java 6 spec on serialization:


The goals are to:

  • Support bidirectional communication between different versions of a class operating in different virtual machines by:
    • Defining a mechanism that allows JavaTM classes to read streams written by older versions of the same class.
    • Defining a mechanism that allows JavaTM classes to write streams intended to be read by older versions of the same class.
  • Provide default serialization for persistence and for RMI.
  • Perform well and produce compact streams in simple cases, so that RMI can use serialization.
  • Be able to identify and load classes that match the exact class used to write the stream.
  • Keep the overhead low for nonversioned classes.
  • Use a stream format that allows the traversal of the stream without having to invoke methods specific to the objects saved in the stream.


McDowell
A: 

The serialization mechanism in 1.5 and 1.6 is compatible. Thus, the same code compiled/running in a 1.5 and 1.6 context can exchange serialized objects. Whether the two VM instances have the same/compatible version of the class (as may be indicated by the serialVersionUID field) is a different question not related to the JDK version.

If you have one serializable Foo.java and use this in a 1.5 and 1.6 JDK/VM, serialized instances of Foo created by one V; can be deserialized by the other.

VoidPointer
A: 

Note that the Java Beans specification details a version-independent serialization method which allows for strong backwards-compatibility. It also results in readable "serialized" forms. In fact a serialized object can be created pretty easily using the mechanism.

Look up the documentation to the XMLEncoder and XMLDecoder classes.

I wouldn't use this for passing an object over the wire necessarily (though if high performance is a requirement,I wouldn't use serialization either) but it's invaluable for persistent object storage.

oxbow_lakes
A: 

It is not safe to mix java 1.5 and 1.6. For e.g I have a java 1.5 objects serialized into a file and tried opening in java 1.6 but it came up with the below error

java.io.InvalidClassException: javax.swing.JComponent; local class incompatible: stream classdesc serialVersionUID = 7917968344860800289, local class serialVersionUID = -1030230214076481435 at java.io.ObjectStreamClass.initNonProxy(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readArray(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readArray(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.defaultReadFields(Unknown Source) at java.io.ObjectInputStream.readSerialData(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source)