Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java serialization - incompatible serialVersionUID

I understand the theory behind incompatible serialVersionUIDs (i.e. you can discriminate different compilation versions of the same class) but I am seeing an issue that I don't understand and doesn't fall into the obvious error causes (different compiled version of the same class).

I am testing a serialization/deserialization process. All code is running on one machine, in the same VM, and both serialization and deserialization methods are using the same version of the compiled class. Serialization works fine. The class being serialized is quite complex, contains a number of other classes (java types and UDTs), and contains reference cycles. I haven't declared my own UID in any class.

This is the code:

public class Test {

    public static void main(String[] args) throws Exception {

        ContextNode context = WorkflowBuilder.getSimpleSequentialContextNode();
        String contextString = BinarySerialization.serializeToString(context);
        ContextNode contextD = BinarySerialization.deserializeFromString(ContextNode.class, contextString);
    }
}

public class BinarySerialization {

    public static synchronized String serializeToString(Object obj) throws Exception {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(byteStream);
        oos.writeObject(obj);
        oos.close();
        return byteStream.toString();
    }

    public static synchronized <T> T deserializeFromString(Class<T> type, String byteString) throws Exception {
        T object = null;
        ByteArrayInputStream byteStream = new ByteArrayInputStream(byteString.getBytes());
        ObjectInputStream in = new ObjectInputStream(byteStream);
        object = (T)in.readObject();
        in.close();
        return object;
    }
}

I am getting an InvalidClassException (local class incompatible: stream classdesc serialVersionUID = -7189235121689378989, local class serialVersionUID = -7189235121689362093) when deserializing.

What is the underlying issue? And how should I fix it?

Thanks

Edit I should state the purpose of this. The serialized data will both need to be stored in a sqlite database and sent across the wire to other clients. If String is the wrong format for passing around the serialized data, what should I be using instead that will let me store and pass the data about? Thanks again.

like image 507
MalcomTucker Avatar asked Dec 17 '22 22:12

MalcomTucker


1 Answers

First rule: never use String or char[] or Reader or Writer when handling binary data.

You're handling binary data and try to put it into a String. Don't do that, that's an inherently broken operation.

Next: the return value of byteStream.toString() doesn't in any way represent the actual content of the ByteArrayOutputStream. You'll want to use .getBytes() and pass the byte[] around (remember: treat binary data as binary data and not as a String).

like image 164
Joachim Sauer Avatar answered Dec 27 '22 20:12

Joachim Sauer