I have compiled and jarred the various projects in my Java application, generating serialVersionUIDs automatically through Eclipse for all my classes derived from Serializable.
I read the answers to this question, and verified that serialVersionUids are all private static final long.
Nevertheless, I get an error like this when I try to run:
java.io.InvalidClassException: com.acme.product.Widget; local class
incompatible: stream classdesc serialVersionUID = 5226096973188250357, local
class serialVersionUID = -5432967318654384362
What am I missing?
You probably have a classpath issue, where your program is resolving an older incompatible version of the class which has a different value for serialVersionUID.
Or the serialized object that is being loaded, was serialized with an oder version of the class which is now unavailable.
If the class has changed since you serialized it, the change may be incompatible. Serialization can't deserialize it, even with the included serialVersionUID.
If you have the class as it was when serialized (e.g. from SCM), then try reverting back to that, regenerate the serialVersionUID and rerun.
If you have made incompatible changes, then you will have to implement readObject() /writeObject() to handle the serialization details yourself.
stream classdesc serialVersionUID =
5226096973188250357
What am I missing?
What you are missing is private static final long serialVersionUID = 5226096973188250357L;
However if the changed class is no longer serialization-compatible (see the Object Serialization Specification) you may now get more obscure errors.
Related
I have old binary data serialized and stored in a db with an old class 'mypackage.Myclass'
I would like to refactor this class to 'mypackage.topic.Myclass' and still able to read the binary data back (deserialization)
I get an error Classnotfound when :
ois = new ObjectInputStream(bos);
o = ois.readObject();
mypackage.topic.Myclass myclass = (mypackage.topic.Myclass) o;
Is there a way to force readObject() to match another class then the original serialized class ? Or any otherhint doing this ?
You can solve this by creating a data wrapper class called mypackage.Myclass. When deserializing the binary data, you can first try to deserialize it as mypackage.topic.Myclass. When this fails, deserialize it as mypackage.Myclass and convert it afterwards to the class mypackage.topic.Myclass.
You can also set the serialVersionUID of the mypackage.topic.Myclass to the serialVersionUID of the mypackage.Myclass. If you don't know the serialVersionUID of the class mypackage.Myclass, or if you doesn't have set the serialVersionUID, you can generate the serialVersionUID, which is probably used/automatically created by the JVM using this command: serialver -classpath whatever com.foo.bar.MyClass (See: Java - Modifying serialVersionUID of binary serialized object)
When the classes have the same serialVersionUID, there will be no error when you deserialize the class.
I'm currently writing a project where I have a serializable class ClientRepository. The class don't specifies any serialVersionUID.
When I try to run my program, I got following Exception:
Exception in thread "main" java.io.InvalidClassException: ClientRepository; local class incompatible: stream classdesc serialVersionUID = -477189107700903771, local class serialVersionUID = -3576242897222506440
So I added a default serialVersionUID (1L), but now I get
Exception in thread "main" java.io.InvalidClassException: ClientRepository; local class incompatible: stream classdesc serialVersionUID = -477189107700903771, local class serialVersionUID = 1
How can I change the "stream classdesc serialVersionUID" to 1L, so it won't conflict?
Thanks!
Don't try to change the data - instead, if you're certain that your class is still compatible with the old version (and if only one version has data out in the wild), change your declared serialVersionUID to -477189107700903771L to match the value in the data. The value is arbitrary - it just has to match what's in the data.
Of course, if your class has changed in an incompatible way, you'll need to write some custom serialization code.
Personally I try to avoid native binary serialization like this for precisely these brittleness reasons. You might wish to look at alternatives such as Protocol Buffers.
The problem is probably the objects that were serialized into the repository before adding serialVersionUID = 1L - they still have generated serialVersionUID that is different from 1L. You should purge the repository.
I'm getting a serialization compatibility error from the below two classes. Only the parent class, CommericalCustomer implements serialization. What is the proper way to use the Serializable Interface when having a parent/child relation as I have below?
public class CachedCommercialCustomers extends CommercialCustomer {
}
public class CommercialCustomer implements Serializable {
private static final long serialVersionUID = 1L;
}
Exception:
[#|2013-01-02T05:01:02.553-0800|SEVERE|glassfish3.1.2|com.hazelcast.nio.AbstractSerializer|_ThreadID=10;_ThreadName=Thread-2;|spot.api.model.vo.backoffice.CachedCommercialCustomers; local class incompatible: stream classdesc serialVersionUID = -2672531984245897526, local class serialVersionUID = -743225273062282831
java.io.InvalidClassException: com.sample.CachedCommercialCustomers; local class incompatible: stream classdesc serialVersionUID = -2672531984245897526, local class serialVersionUID = -743225273062282831
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:579)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1600)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346)
at java.io.ObjectInputStream.readUnshared(ObjectInputStream.java:458)
at com.hazelcast.nio.DefaultSerializer$ObjectSerializer.readNormal(DefaultSerializer.java:383)
at com.hazelcast.nio.DefaultSerializer$ObjectSerializer.read(DefaultSerializer.java:353)
at com.hazelcast.nio.DefaultSerializer.read(DefaultSerializer.java:134)
at com.hazelcast.nio.CustomSerializerAdapter.read(CustomSerializerAdapter.java:33)
at com.hazelcast.nio.AbstractSerializer.toObject(AbstractSerializer.java:116)
at com.hazelcast.nio.AbstractSerializer.toObject(AbstractSerializer.java:146)
at com.hazelcast.nio.Serializer.readObject(Serializer.java:72)
at com.hazelcast.impl.ThreadContext.toObject(ThreadContext.java:103)
at com.hazelcast.nio.IOUtil.toObject(IOUtil.java:149)
at com.hazelcast.impl.BaseManager$RequestBasedCall.getResultAsObject(BaseManager.java:384)
at com.hazelcast.impl.BaseManager$ResponseQueueCall.getResultAsObject(BaseManager.java:455)
at com.hazelcast.impl.BaseManager$RequestBasedCall.getResultAsObject(BaseManager.java:368)
at com.hazelcast.impl.BaseManager$ResponseQueueCall.getResultAsObject(BaseManager.java:455)
The problem here is that you don't specify a serialVersionId for your sub class - so java will generate one for you instead. A simple recompilation might change this value if you change the java source file. See the spec.
The fact that the I'd changes when the code changes is a good thing, but in some cases it will cause you some grief :)
See here for more information and how to "fix" the problem if necessary.
I had saved one java object in the Database and then after few days I changed my jre version.
Now when i tried to read that same object I am getting following exception:
Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
serialVersionUID = -6377573678240024862, local class serialVersionUID = -8204757486033751616
How can I get rid of this,how can I get the saved object?
please help me.
If you can affect source code of this class and JRE was only thing that changed, most likely you can still deserialize object that was serialized by older JVM. Just define following field in class to be deserialized:
private static final long serialVersionUID = -6377573678240024862L;
I am getting the following serialization error and I am trying to read my object that I saved to a file
java.io.InvalidClassException: com.testGame.scoreCard; Incompatible class (SUID): com.testGame.scoreCard: static final long serialVersionUID =-5895378336422852901L; but expected com.testGame.scoreCard: static final long serialVersionUID =0L;
at java.io.ObjectInputStream.verifyAndInit(ObjectInputStream.java:2376)
at java.io.ObjectInputStream.readNewClassDesc(ObjectInputStream.java:1658)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:683)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1799)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1999)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1956)
But what I don't get is why scoreCard is serialized in the first place? The class(object) that I am writing and reading is serialized and does not call or make use of scoreCard class. Why would it complain about that class? Is there a way to see why this scoreCard is involved? ( I am using eclipse btw)
Thank you
Are you perhaps serializing an inner class of ScoreCard? They have secret references to the containing object.
Could it be that class that you are trying to restore depends indirectly on ScoreCard, through another class for example?
To see dependencies in Eclipse you can click on a class name or method name and press Ctrl+Shift+G, it will show you all the places where class or method is used.
Another way to discover dependencies is to click on a method name and press Ctrl+Alt+H, it will show you call graph that you can discover further.