Redis Serialization and Deserialization
Asked Answered
S

1

12

I have noticed that some of my serialized objects stored in Redis have problems deserializing.

This typically occurs when I make changes to the object class being stored in Redis.

I want to understand the problem so that I can have a clear design for a solution.

My question is, what causes deserialization problems? Would a removal of a public/private property cause a problem? Adding new properties, perhaps? Would a adding a new function to the class create problems? How about more constructors?

In my serialized object, I have a property Map, what if I change (updated some properties, added functions, etc) myObject, would it cause a deserialization problem?

Sensationalism answered 12/6, 2015 at 4:21 Comment(0)
L
26

what causes deserialization problems?

I would like to give you bit of background before answering your question,

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException.

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, It uses the following information of the class to compute SerialVersionUID,

  1. The class name.
  2. The class modifiers written as a 32-bit integer.
  3. The name of each interface sorted by name.
  4. For each field of the class sorted by field name (except private static and private transient fields:
  5. The name of the field.
  6. The modifiers of the field written as a 32-bit integer.
  7. The descriptor of the field.
  8. if a class initializer exists, write out the following:

    The name of the method, .

    The modifier of the method, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.

    The descriptor of the method, ()V.

  9. For each non-private constructor sorted by method name and signature:

    The name of the method, .

    The modifiers of the method written as a 32-bit integer.

    The descriptor of the method.

  10. For each non-private method sorted by method name and signature:

    The name of the method.

    The modifiers of the method written as a 32-bit integer.

    The descriptor of the method.

So, to answer your question,

Would a removal of a public/private property cause a problem? Adding new properties, perhaps? Would a adding a new function to the class create problems? How about more constructors?

Yes, all these additions/removal by default will cause the problem.

But one way to overcome this is to explicitly define the SerialVersionUID, this will tell the serialization system that i know the class will evolve (or evolved) over the time and don't throw an error. So the de-serialization system reads only those fields that are present in both the side and assigns the value. Newly added fields on the de-serialization side will get the default values. If some fields are deleted on the de-serialization side, the algorithm just reads and skips.

Following is the way one can declare the SerialVersionUID,

private static final long serialVersionUID = 3487495895819393L;
Lipp answered 12/6, 2015 at 4:52 Comment(4)
Thank you very much for this informative answer. I do have another question just to be clear. When you say "explicitly define the SerialVersionUID", is that ok to define this UID as default "private static final long serialVersionUID = 1L;"?Sensationalism
I mean, if the CLASS DOES NOT declare a UID, then it would use the DEFAULT. But! What if I declare a UID, but still the value is DEFAULT? Would it still compute a UID?Sensationalism
Hi, yes you can define any value as long as the values are same on both the sides. By the way 1L is not the default value, you can think it as a version number.Lipp
So should the serialVersionUID itself be transient or not? I guess not, but then it might use up a lot of memory storing the same value over and over in redis?Mesnalty

© 2022 - 2024 — McMap. All rights reserved.