RP-
RP-

Reputation: 5837

Deserialize an object after the underlying class structure got changed

We were serializing some Data objects and storing them in the database, There were hundreds of such objects in the database since longtime. Recently We needed change structure of one of those classes. Now The deserializing those object is throwing errors.

We have not written custom serialization and deserialization earlier. The use of defaultSerialVersionUID is also not helping us here as it was just default 1L while serializing them.

Is there any better way to deserialize them after the underlying Class structure got changed?

Upvotes: 0

Views: 3969

Answers (3)

user207421
user207421

Reputation: 310883

The first thing you should have read before doing those changes is the Object Versioning chapter of the Object Serialization Specification. It lays out exactly what you can and can't do while preserving compatibility with existing Serializations. It allows a lot more than most people seem to think, but it doesn't allow for example changes in the inheritance chain, which is what it sounds like you've done.

The second thing you will have to do is back out those changes that don't comply.

Upvotes: 1

Stephen C
Stephen C

Reputation: 718788

We were serializing some Data objects and storing them in the database ...

That was/is a big mistake, IMO. You avoided you having to build and maintain tables corresponding to the data objects ... but Java object serialization is not designed for this kind of thing, and this kind of fragility is one of the downsides.


@EJP and @sidoh's answers provide some ideas for digging yourself out of your current hole provided that you can get hold of the old versions of the classes. There are a couple of approaches:

  • Roll back to the code / schema state before the changes that broke compatibility ... and redo the work in a way that avoids the mistake.

  • Don't rollback, but write some ad-hoc converter that loads the currently readable objects into a readable form and updates the stored versions.

The former may be impractical; e.g. if too much else has changed, or if your code / data is in production.

The latter involves retrieving the old and new versions of the classes from version control and building an ad-hoc converter that loads with the old classes, translates to instances of the new classes and saves. The difficulty of this is that building a Java application that can simultaneously use two different versions of the same classes in the same JVM:

  • You can instantiate two classloaders with the different versions on their classpaths. But the problem is that the JVM will treat the two sets of classes as different types, and that will make static binding against both versions impossible. You could deal with this via reflection ... but it will be very messy, especially if the respective object APIs are extensive.

  • You could do this as a two-stage process. Stage 1 is to load using the old classes and then serialize the classes using (say) JSON which you write to a file (say). Stage 2 is to read the JSON, use it to create objects using the new classes, and serialize them using object serialization.


A third alternative would be to write an ad-hoc converter that tweaks the serialized objects. Basically, you need to get your head around the differences between the old and new serialized forms and then rewrites the serialized objects by reading / writing them using some low-level API. A variation of this would be to implement a custom readObject and method in the new version of the class that understands both the old and new formats. However, this could be tricky given that your old objects don't have any custom version fields. It should be noted that this kind of stuff is beyond the scope of the serialization spec ...


But IMO the best alternative is to use this as an opportunity to STOP using Java Serialization. Read the objects using the old classes, and then write them back to the database into regular SQL tables, as JSON or XML blobs, or using an ORM mapping.

Upvotes: 3

sidoh
sidoh

Reputation: 590

Going forward, I'd highly recommend something something like Thrift. It was developed in part to solve exactly this problem.

As for solving the problem at hand, can you revert the changes? Deserialize the objects, put the fields from the old data into new objects, and serialize the new ones.

Upvotes: 2

Related Questions