Consider the following situation, described in question How can I deserialize the object, if it was moved to another package or renamed? by dma_k:
There is a serialization file, created by the older version of the application. Unfortunately, the package has changed for the class, that has been serialized. And now I need to load the information from this file into the same class, but located in different package. This class has serialVersionUID defined and has not changed (i.e. is compatible).
Question was: Is it possible to load the new class instances from this file using any tricks (except trivial copying the class into old package and then using the deserialization wrapper logic)? ...
Solution was "class HackedObjectInputStream extends ObjectInputStream" by Igor Nardin:
class HackedObjectInputStream extends ObjectInputStream {
public HackedObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
if (resultClassDescriptor.getName().equals("oldpackage.Clazz"))
resultClassDescriptor = ObjectStreamClass.lookup(newpackage.Clazz.class);
return resultClassDescriptor;
}
}
Follow-up question Is it possible to write the new class instances to a file in a backward compatible way (explicitly setting the class name)? The goal is that older applications can read the files written by the new application (with the package name changed).
How would a "class HackedObjectOutputStream extends ObjectOutputStream" look like?
public class HackedObjectOutputStream extends ObjectOutputStream {
public HackedObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
@Override
public final void writeObjectOverride(Object obj) throws IOException {
// How to change the package.class name ?
}
}