paweloque
paweloque

Reputation: 18864

Finding serialVersionUID of serialized object

Is there a way to determine the generated serialVersionUID of a serialized Java object?

The problem is that I serialized an object without explicitely specifying the serialVersionUID. Now the deserialization process complains about class incompatibilities. However I didn't change the class in a way which would make it incompatible. So I assume that it is enough to specify the serialVersionUID in the class as it is stored in the object data. In order to do this I need to read the serialVersionUID from the serialized data.

Upvotes: 25

Views: 24683

Answers (9)

FindOut_Quran
FindOut_Quran

Reputation: 768

The easiest way to get it (especially on hard to find cases) is to define any number for serialVersionUID and monitor the stacktrace when the deserialization fails, it will print out the original one.

Upvotes: 1

shanwu
shanwu

Reputation: 1675

enter image description here for Android developers,

you can also enable serialization inspection from Settings -> Editor -> Inspections -> enable "Serializable class without 'serialVersionUID' check" first, then ALT+ ENTER, the studio will create serialVersionUID for you.

Upvotes: 1

psychollek
psychollek

Reputation: 323

there is much simpler way to get the serialVersionUID of serialized object - just deserialize it with apache commons serialization utils to same class with different serial version uid and read the exception message which will be more or less:

org.apache.commons.lang.SerializationException: java.io.InvalidClassException: my.example.SerializableClass; local class incompatible: stream classdesc serialVersionUID = -1, local class serialVersionUID = -2

Upvotes: 0

Martins
Martins

Reputation: 1261

This works for me:

long serialVersionUID = ObjectStreamClass.lookup(YourObject.getClass()).getSerialVersionUID();

Hope it helps you too.

Upvotes: 34

Keshav
Keshav

Reputation: 4478

There's an easy way to find out serialversionUID of a class-

Suppose you have class in which you have forgotten to mention serialversionUID-

import java.io.Serializable;

public class TestSerializable implements Serializable {

}

Just do this-

serialver -classpath . TestSerializable

This prints-

static final long serialVersionUID = 5832063776451490808L;

serialver is a utility that comes along with JDK

Upvotes: 27

user159088
user159088

Reputation:

There is metadata associated with the serialized bits (a header if you like). You can read the value from the metadata if you know at which position it is (the SerialVersionUID is written there along with other info such as the class name).

I think this article might help you: The Java serialization algorithm revealed.

Note that the bits are written "in clear" (unless you encrypted the stream explicitly) so a HEX editor might be all you need to see what is the SerialVersionUID.

Upvotes: 5

McDowell
McDowell

Reputation: 108859

You can do this by extending ObjectInputStream:

public class PrintUIDs extends ObjectInputStream {

  public PrintUIDs(InputStream in) throws IOException {
    super(in);
  }

  @Override
  protected ObjectStreamClass readClassDescriptor() throws IOException,
      ClassNotFoundException {
    ObjectStreamClass descriptor = super.readClassDescriptor();
    System.out.println("name=" + descriptor.getName());
    System.out.println("serialVersionUID=" + descriptor.getSerialVersionUID());
    return descriptor;
  }

  public static void main(String[] args) throws IOException,
      ClassNotFoundException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    List<Object> list = Arrays.asList((Object) new Date(), UUID.randomUUID());
    oos.writeObject(list);
    oos.close();
    InputStream in = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new PrintUIDs(in);
    ois.readObject();
  }

}

I believe it would be possible to read all the serialized data by replacing the descriptor returned by the method, but I haven't tried it.

Upvotes: 13

Nick Holt
Nick Holt

Reputation: 34301

That's exactly what you should do - specify your own static final long serialVersionUID.

There's a section about it in the docs for Serializable.

Unless you've specified a serialVersionUID I don't believe there's an easy way to get it other than deciphering the stream as @WMR suggests.

Upvotes: 0

WMR
WMR

Reputation: 12971

There is a specified grammar for the serialization of objects:

See chapter 6.4 in http://java.sun.com/javase/6/docs/platform/serialization/spec/serialTOC.html

Using this, you should be able to determine the SerialVersionUID of your serialized object.

Upvotes: 1

Related Questions