Java: Work out the serialVersionUID of a class
Earlier in the week I wanted to work out the serialVersionUID of a serializable class so that I could override its toString method without breaking everything.
I came across Frank Kim’s blog post which suggested using the serialver tool which comes with the JDK.
I created a little Maven project to test this tool out on a very simple class:
import java.io.Serializable;
public class SerialiseMe implements Serializable
{
}
If we compile that class into a JAR and then run the serialver tool we see the following output:
$ serialver -classpath target/serialiser-0.0.1-SNAPSHOT.jar SerialiseMe
SerialiseMe: static final long serialVersionUID = -6060222249255158490L;
I wanted to quickly confirm that I could serialise and deserialise this class using this value so I wrote the following bit of code to serialise the class (when it didn’t have a serial version UID):
public class Serialiser
{
public static void main( String[] args ) throws IOException, ClassNotFoundException
{
ByteArrayOutputStream bout = new ByteArrayOutputStream( );
ObjectOutputStream oout = new ObjectOutputStream( bout );
Object value = new SerialiseMe();
oout.writeObject( value );
oout.close();
byte[] bytes = bout.toByteArray();
FileOutputStream fileOuputStream = new FileOutputStream("/tmp/foo.txt");
fileOuputStream.write(bytes);
fileOuputStream.close();
}
}
After I’d done that, I wrote the following bit of code to deserialise the file:
public class Deserialiser
{
public static void main( String[] args ) throws IOException, ClassNotFoundException
{
FileInputStream fileInputStream = new FileInputStream( new File( "/tmp/foo.txt" ) );
byte[] bytes = IOUtils.toByteArray( fileInputStream );
ByteArrayInputStream in = new ByteArrayInputStream( bytes, 0, bytes.length );
ObjectInputStream oin = new ObjectInputStream( in );
Object object = oin.readObject();
}
}
I plugged the serial version UID into the class and was able to deserialise it correctly. I tried changing one of the digits just to check it would blow up and indeed it did:
import java.io.Serializable;
public class SerialiseMe implements Serializable
{
static final long serialVersionUID = -6060222249255158491L;
}
Exception in thread "main" java.io.InvalidClassException: SerialiseMe; local class incompatible: stream classdesc serialVersionUID = -6060222249255158490, local class serialVersionUID = -6060222249255158491
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:604)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Deserialiser.main(Deserialiser.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
serialver #ftw!
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.