How can I deserialize the object, if it was moved to another package or renamed?
It is possible:
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;
}
}
This also allows one to ignore serialVersionUIDs mismatch or even deserialize a class if its field structure was changed.
Question: 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)?
I don't think there are any other "tricks" you could use that don't involve at least a partial reimplementation of the serialization protocol.
Edit: there is in fact a hook that allows this if you control the deserialization process, see the other answer.
It is possible to use readResolve() to recover from moving/renaming the class? If not, please, explain why.
No, because the deserialization mechanism will fail much earlier, at the stage where it tries to locate the class that's being deserialized - it has no way of knowing that a class in a different package has a readResolve()
method it's supposed to use.