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?
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.
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.
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.
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.
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.