11

It's well known that runtime will genereate serialVersionUID field for your class, if you failed to explicitly define it.

But is it possible to get this value in runitme? Is it possible in runtime, having reference to .class, obtain it's serialVersionUID?

ivstas
  • 1,203
  • 1
  • 16
  • 31
  • 2
    What do you want this information for, if I may ask? It is used internally by the JVM for {de,}serialization, you shouldn't have to care about it... – fge Mar 04 '14 at 10:28
  • Of course it's possible. ObjectInputStream does it. – user207421 Mar 04 '14 at 10:54
  • @fge I expected this question. Actually, I use infinispan cache library with file cache, which forces me to use serializable class. Serializable instances of these classes survives JVM restart. The problem is that when I change internal structures of the file and update serialVersionUID, infinispan is still capable to deserialize this instances to application, which is a problem. – ivstas Mar 04 '14 at 11:53
  • @fge I wrote code, which manually checks serialVersionUID and skips deserialization instances of old versions of class. The only problem that I need to manually keep track on changes of the class. What I want - to force my code change serialVersionUID automatically. – ivstas Mar 04 '14 at 11:55
  • @fge typo "when I change internal structure of these **classes**" – ivstas Mar 04 '14 at 12:00

3 Answers3

24
 Integer i = new Integer(5);
 long serialVersionID = ObjectStreamClass.lookup(i.getClass()).getSerialVersionUID();

Above is the sample code to get serial version id of the class at runtime.

Sagar Gandhi
  • 925
  • 6
  • 20
  • Perfect! That's actually does what I wanted. – ivstas Mar 04 '14 at 12:25
  • Note however the docs: > "Null is returned if the specified class does not implement java.io.Serializable or java.io.Externalizable." You'd maybe assume that classes that are to be serialized implement this interface but it seems some frameworks use other marker mechanisms. – Marcus Philip Nov 15 '21 at 09:57
2

Sure you can. serialVersionUID is a regular static variable, so you can access it when you want. The only problem is that it is typically defined as private or protected, so you can access it from the class itself only. To access it from outside you can use reflection:

Class<?> clazz = obj.getClass();
Field f = clazz.getDeclraredField("serialVersionUID");
f.setAccessible(true);
long uid = (long)f.getValue();
AlexR
  • 114,158
  • 16
  • 130
  • 208
  • Are you sure? I get java.lang.NoSuchFieldException: serialVersionUID – ivstas Mar 04 '14 at 12:21
  • In fact I'm trying to force java runtime to **create** this field for class which has not explicitly specified it. – ivstas Mar 04 '14 at 12:22
  • @Kite It already does that, automatically. There are serious problems with your question and your approach. See my answers – user207421 Mar 04 '14 at 23:54
  • On the other hand this is the only way I've found to get to know if the class defines own serialVersionUid or uses the one automatically generated by the compiler. – Lukasz Frankowski May 21 '20 at 09:56
2

What I want: to force my code [to] change serialVersionUID automatically ... when I change internal structure of these classes.

No you don't. You want to keep the serialVersionUID the same forever, and to restrict the internal changes to what can be handled automatically by Serialization, for which you need to consult the Versioning chapter of the Object Serialization Specification. Changing the serialVersionUID on every class change is an urban myth which unfortunately has been far too widely propagated and accepted.

And your proposed solution won't work either. 'Skipping deserialization instances of old versions of [a] class' isn't a solution to anything. Serialization will already have rejected it with an exception if the serialVersionUIDs don't agree. Anything you do after that is already too late.

This is sounding like an XY problem. You want to do X, you think Y is the answer, so you ask about Y, when you should be asking about X. For the correct solution see above.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I have Serialization Proxy Class, which is serialized manually with NON-JDK serialization framework. I have two methods which manually serialize-and-de-serialize this proxy. In these methods I serialize class version, serialize the object itself (this time using standard JDK serialization). For me it's **way more convinient** to throw away **cached** instances if they are from previous version of the class. Anyway - **thank you for the link about versioning chapter, I will investigate it deeper** – ivstas Mar 05 '14 at 05:11
  • You needed to provide a lot more of this detail in your question. Otherwise everybody just wonders what you're doing it all for. – user207421 Mar 05 '14 at 06:12