Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.io.InvalidClassException:

InvalidClassException: local class incompatible: stream classdesc serialVersionUID = -196410440475012755, local class serialVersionUID = -6675950253085108747

I struct with the InvalidClassException in the following scenario. Here my EAR is installed in 4 Websphere App servers and execution is shared among this. Sometimes I got the exception InvalidClassException from POJO class, Which is implements Serializable interface. Please any clue on this. I don't have any clue regarding to this.

like image 957
karthik Avatar asked Aug 24 '11 09:08

karthik


2 Answers

When you implement java.io.Serializable interface to make a class serializable, the compiler looks for a static, final field named "serialVersionUID" of type long. If the class doesn't have this field declared explicitly then the compiler will create one such field and assign it with a value which comes out of a implementation dependent computation of serialVersionUID. This computation depends upon various aspects of the class and it follows the Object Serialization Specifications given by Sun. But, the value is not guaranteed to be the same across all compiler implementations.

This value is used for checking the compatibility of the classes with respect to serialization and this is done while de-serializing a saved object. The Serialization Runtime verifies that the serialVersionUID of the sender class (which was used for saving the state of the object on the stream) and that of the receiver class (the class which is being used to restore the object, possibly at some other system) both are exactly same. If the receiver system has loaded the class having some other serialVersionUID than that of the class used while serialization process then we get an InvalidClassException.

NOTE-- It's highly recommended that you explicitly declare and initialize the static, final field of type long and named 'serialVersionUID' in all your classes you want to make Serializable instead of relying on the default computation of the value for this field. This computation is extremely sensitive and may vary from one compiler implementation to another and hence you may turn up getting the InvalidClassException even for the same class just because you used different compiler implementations on the sender and the receiver ends of the serialization process.

In most of the cases you would be using 'private' access specifier only for this field as the declaration normally applies only to the class declaring it and we don't really need to either inherit this field in the subclasses OR to access it from outside. So, there is hardly any reason why we shouldn't keep it 'private'.

like image 143
amod Avatar answered Sep 25 '22 11:09

amod


You get that exception when you try to deserialize an object that was serialized with an incompatible (usually earlier) version of the same class.

If you don't explicitly specify a serialVersionUID in your class implementing Serializable, then a value will be generated based on the (non-transient) fields of your class. This is done to ensure that no partial objects are restored (it's better to fail than to blindly continue with a probably-broken object).

In web-application systems, a common use of serialization is for the session: if you put a value into the session, it's likely that it will be serialized eventually (for clustering support or simply to get persistent sessions).

So either keep all your classes compatible between versions or ensure that not restoring them does not break your application (i.e. don't store important information this way).

like image 21
Joachim Sauer Avatar answered Sep 25 '22 11:09

Joachim Sauer