How to deserialize an object persisted in a db now when the object has different serialVersionUID

后端 未结 6 1928
太阳男子
太阳男子 2020-12-14 04:34

My client has an oracle data base and an object was persisted as a blob field via objOutStream.writeObject, the object now has a different serialVersionUID (eve

6条回答
  •  北海茫月
    2020-12-14 05:09

    I may be missing something, but it sounds like you're trying to do something more complicated than necessary. What happens if:

    (a) you take the current class definition (i.e. the source code) and hard-code its serial UID to the old one (or one of the old ones), then use that class definition to deserialise the serialised instances?

    (b) in the byte stream you're reading, you replace the old serial UIDs with the new one before wrapping the ObjectInputStream around them?

    OK, just to clarify (b). So for example, if I have a little class like this:

      public static class MyClass implements Serializable {
        static final long serialVersionUID = 0x1122334455667788L;
        private int myField = 0xff;
      }
    

    then when the data is serialised, it looks something like this:

    ACED000573720011746573742E546573 ’..sr..test.Tes
    74244D79436C61737311223344556677 t$MyClass."3DUfw
    880200014900076D794669656C647870 ?...I..myFieldxp
    000000FF ...ÿ
    

    Each line is 16 bytes, and each byte is 2 hex digits. If you look carefully, on the second line, 9 bytes (18 digits) in, you'll see the serial version ID starts (1122...). So in our data here (yours will differ slightly), the offset of the serial version ID is 16 + 9 = 25 (or 0x19 in hex). So before I start deserialising, if I want to change this serial version ID to something else, then I need to write my new number at offset 25:

    byte[] bytes = ... serialised data ...
    ByteBuffer bb = ByteBuffer.wrap(bytes);
    bb.putLong(25, newSerialVersionUID);
    

    then I just proceed as normal:

    ObjectInputStream oin = new ObjectInputStream(new ByteArrayInputStream(bytes));
    MyClass obj = (MyClass) oin.readObject();
    

提交回复
热议问题