views:

1140

answers:

5

I have one java program that has to be compiled as 1.4, and another program that could be anything (so, 1.4 or 1.6), and the two need to pass serialized objects back and forth. If I define a serializable class in a place where both programs can see it, will java's serialization still work, or do I need 1.6-1.6 or 1.4-1.4 only?

+4  A: 

Make sure the classes to be serialized define and assign a value to static final long serialVersionUID and you should be ok.

That said, normally I would not do this. My preference is to only use normal serialization either within a single process, or between two processes are on the same machine and getting the serialized classes out of the same jar file. If that's not the case, serializing to XML is the better and safer choice.

Paul Tomblin
+1  A: 

Java library classes should have compatible serialised forms between 1.4 and 1.6 unless otherwsie stated. Swing explicitly states that it is not compatible between versions, so if you are trying to serialise Swing objects then you are out of luck.

You may run into problems where the code generated by javac is slightly different. This will change the serialVersionUID. You should ensure you explicitly declare the UID in all your serialisable classes.

Tom Hawtin - tackline
If you don't explicitly declare serialVersionUID, you can get the exception about different versions from two different compiles with the exact same code with the exact same compiler with the exact same environment.
Paul Tomblin
@Paul: I thought the default serialVersionUID was well specified as a function of the class members. I have never seen it spuriously change. Can you describe a scenario where this occurs?
erickson
Yup, it would be an odd compiler than added randomness to the data used to calculate serialVersionUID (although technically within spec, I believe).
Tom Hawtin - tackline
I didn't think it would be different either, but read the note in section 4.6 here http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/class.html#4100
Robin
"computation is highly sensitive to class details that may vary depending on compiler implementations" - but if these are kept constant, then it would be an odd (but not necessarily incompatible) compiler that varied UID.
Tom Hawtin - tackline
I agree with Tom. In fact, I've seen a JVM fail to create proper serialversionUID, but it was a bug that the vendor acknowledged (in a specific version of JRockit).BTW, it's not a compiler that calculates the serialVersionUID; for the bug I just talked about, I ran "serialver" from Sun and JRockit and it gave different results.
Nicolas
+3  A: 

Along with the serialVersionUID the package structure has to remain consistent for serialization, so if you had myjar.mypackage.myclass in 1.4 you have to have myjar.mypackage.myclass in 1.6.

It is not uncommon to have the Java version or your release version somewhere in the package structure. Even if the serialVersionUID remains the same between compilations the package structure will cause an incompatible version exception to get thrown at runtime.

BTW if you implement Serializable in your classes you should get a compiler warning if serialVersionUID is missing.

In my view (and based on some years of quite bitter experience) Java native serialization is fraught with problems and ought to be avoided if possible, especially as there is excellent XML/JSON support. If you do have to serialize natively, then I recommend that you hide your classes behind interfaces and implement a factory pattern in the background which will create an object of the right class when needed.

You can also use this abstraction for detecting the incompatible version exception and doing whatever conversion is necessary behind the scenes for migration of the data in your objects.

Simon
A: 

If both sides uses the same jar file, it will work most of the times. However if you use different versions of the same package/module/framework ( for instance different weblogic jars or extended usage of some "rare" exceptions ) a lot of integration test is needed before it can be approved.

OscarRyz
+1  A: 

No, different version of the JVM will not break the serialization itself.

If some of the objects you are serializing are from the Java runtime, and their classes have evolved incompatibly, you will see failures. Most core Java classes are careful about this, but there have been discontinuities in some packages in the past.

I've successfully used serialization (in the context of RMI) with classes from different compilations on different machines running different versions of the Java runtime for years.

I don't want to digress too far from the original question, but I want to note that evolving a serialized class always requires care, regardless of the format. It is not an issue specific to Java serialization. You have to deal with the same concepts whether you serialize in XML, JSON, ASN.1, etc. Java serialization gives a fairly clear specification of what is allowed and how to make the changes that are allowed. Sometimes this is restrictive, other times it is helpful to have a prescription.

erickson