Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java serialization, UID not changed. Can I add new variables and method to the class?

I have a class that is serialised. Now I need to add a new variable into the class, with setter and getter methods. This class is sent over wire in RMI.

Without changing the UID, can I add new parameters and getter and setter methods for it? I tried to write an example class that is sent over wire, and did not change the UID, and added new parameters and getter and setter methods for it. On the other end, I tested it and I still got the values properly. I had assumed, if I add new parameters, getter and setter methods, I need to change the UID. Am I wrong?

like image 650
javanerd Avatar asked Nov 08 '10 14:11

javanerd


People also ask

What happens during serialization if I have static variable in class?

In Java, serialization is a concept using which we can write the state of an object into a byte stream so that we can transfer it over the network (using technologies like JPA and RMI). But, static variables belong to class therefore, you cannot serialize static variables in Java.

What happens if object is not serialized?

What happens if you try to send non-serialized Object over network? When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object.

What is the use of UID in serialization?

The SerialVersionUID can be used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible w.r.t serialization. If the deserialization object is different than serialization, then it can throw an InvalidClassException.

Can you customize serialization process?

We can customize Serialization process by defining writeObject() method & DeSerialization process by defining readObject() method. We have serialized id and name manually writing them in file.


4 Answers

If you hard-code the SerialVersionUID of a class, (to 1L, usually), store some instances, and then re-define the class, you basically get this behavior (which is more or less common sense):

  1. New fields (present in class definition, not present in the serialized instance) are assigned a default value, which is null for objects, or the same value as an uninitialized field for primitives.
  2. Removed fields (not present in class definition but present in the serialized instance) are simply ignored.

So the general rule of thumb is, if you simply add fields and methods, and don't change any of the existing stuff, AND if you're OK with default values for these new fields, you're generally OK.

like image 101
romacafe Avatar answered Oct 06 '22 05:10

romacafe


Wow, a lot of bad information.

Java serialization is +very+ robust. There are a very well defined set of rules governing backwards compatibility of objects with the same uid and different data. the basic idea is that as long as you don't change the the type of an existing member, you can maintain the same uid without data issues.

that said, your code still needs to be smart about handling classes with potentially missing data. the object may deserialize correctly, but there may not be data in certain fields (e.g. if you added a field to the class and are deserializing an old version of the class). if your code can handle this, than you can probably keep the current uid. if not, then you should probably change it.

in addition to the pre-defined rules, there are advanced usage scenarios where you could even change the type of existing fields and still manage to deserialize the data, but that generally only necessary in extreme situations.

java serialization is very well documented online, you should be able to find all this information in the relevant sun/oracle tutorials/docs.

like image 20
james Avatar answered Oct 06 '22 04:10

james


Want to define few point to highlight the changes which impacts serialization. Below you will find the link to Oracle Java Docs for more details.

Incompatible Changes

Incompatible changes to classes are those changes for which the guarantee of interoperability cannot be maintained. The incompatible changes that may occur while evolving a class are:

  1. Deleting fields
  2. Moving classes up or down the hierarchy
  3. Changing a nonstatic field to static or a nontransient field to transient
  4. Changing the declared type of a primitive field
  5. Changing the writeObject or readObject method so that it no longer writes or reads the default field data or changing it so that it attempts to write it or read it when the previous version did not.
  6. Changing a class from Serializable to Externalizable or vice versa.
  7. Changing a class from a non-enum type to an enum type or vice versa.
  8. Removing either Serializable or Externalizable.
  9. Adding the writeReplace or readResolve method to a class, if the behavior would produce an object that is incompatible with any older version of the class.

Link from where the above information is taken http://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#6678

like image 37
Varun Avatar answered Oct 06 '22 03:10

Varun


This only matters if you let Java generate a default UID for your class. It uses the actual members and methods of the class to generate it, thus making it invalid once you change the class structure. If you provide an UID for your class then this only matters if you need to deserialize older versions of your class from a file and such.

like image 32
deorst Avatar answered Oct 06 '22 03:10

deorst