This socket will keep receiving some old objects and new objects with same name. However, if I used readObject directly, it will throws fatal exception. Some of us would suggest to ignore old object or change the old object code. This is not possible for me to change client codes. I need to handle the backward-compatibility.
Socket s = ss.accept();
ObjectInputStream lvStream = new ObjectInputStream(s.getInputStream());
Object lvObject = lvStream.readObject();
// The old class but released ( I cannot change it )
public class Apple extends HashMap<String, String> {
private static final long serialVersionUID = 1L;
}
// The old class but released ( I cannot change it )
public class Apple extends HashMap<String, String> {
private static final long serialVersionUID = 2L;
}
// The new class in my local ( 1L or 2L still would not solve the issue easily )
public class Apple extends HashMap<String, String> {
private static final long serialVersionUID = 2L;
}
At the line of readObject(), I got this fatal exception:
java.io.InvalidClassException local class incompatible : stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
How could I read this two kind of Apple objects data (the Hashmap)?
Thank You.
As long as we extend the ObjectInputStream,
we will have access to stream SerialVersionUID to compare with local SerialVersionUID.
Socket s = ss.accept();
// use the extended ObjectInputStream ( DecompressibleInputStream )
DecompressibleInputStreamlvStream = new DecompressibleInputStream(s.getInputStream());
Object lvObject = lvStream.readObject();
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
public class DecompressibleInputStream extends ObjectInputStream {
public DecompressibleInputStream(InputStream in) throws IOException {
super(in);
}
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
Class<?> localClass;
try {
localClass = Class.forName(resultClassDescriptor.getName());
} catch (ClassNotFoundException e) {
System.err.println("No local class for " + resultClassDescriptor.getName());
return resultClassDescriptor;
}
ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookup(localClass);
if (localClassDescriptor != null) {
final long localSUID = localClassDescriptor.getSerialVersionUID();
final long streamSUID = resultClassDescriptor.getSerialVersionUID();
if (streamSUID != localSUID) {
System.err.println("Potentially Fatal Deserialization Operation.");
resultClassDescriptor = localClassDescriptor;
}
}
return resultClassDescriptor;
}
}
hope it helps
(credits to this post)