4

we have a whole bunch of serialized classes but want the database bits to be invalidated whenever the "signature" ie: field structure and serialization code for a class changes,

Is there a utility that can generate a "hash" for a class file that will optimally detect when the serialization structure for java.serializable changes for that class?

peterk
  • 5,136
  • 6
  • 33
  • 47
  • If you re using eclipse you can get eclipse to gen a new id for you. http://stackoverflow.com/questions/3569628/why-isnt-the-serialversionuid-automatically-generated – bhspencer May 30 '15 at 17:37
  • 1
    Why? That just means you would have to throw away the old data. You should be making maximum effort to preserve it. You nee to have a good look at the Versioning chapter of the Object Serialization Specification. There's a lot you can do to a class while retaining serialization compatibility. More than people generally think. You should be constraining your changes to fit within that framework. You're looking at this problem from the wrong end of the telescope. – user207421 May 30 '15 at 19:55
  • @EJP Vanilla serialization (without proxies and other tricks) is really next to useless though for long-term storage in a system that is evolving quickly. So it could well be a valid issue. Having said that, throwing away all legacy data isn't any better. :) – biziclop May 30 '15 at 22:07
  • 2
    @biziclop That is considerably overstated, and in any case that is what the OP is trying to do. What he proposes will make it considerably worse. It is not a 'valid issue' at all. – user207421 May 31 '15 at 01:15
  • @EJP Could be. Either way, it sounds a bit like an X-Y problem. – biziclop May 31 '15 at 10:42
  • I agree that java.serializable is not a good solution this is only due to inherited legacy code - new code we have a system where one has to be explitic about the dtaa format and it has tagged fields instead of ordered fields. – peterk May 31 '15 at 19:40

1 Answers1

3

There's really no way to "optimally detect when a serialization structure changes" for one rather important reason:

Serialization breaks encapsulation.

When you implement Serializable, all the private and package-private fields and members of a class become part of that class's exported API. From the moment that a class is published into the wild, its serialized form (which contains all of its implementation details) is a part of its contract. Changing the serialized form will have one of two consequences:

  • Backward compatibility. Because Serializable breaks encapsulation, the serialized form becomes part of its exported API. When an implementation detail changes, at the developer's discretion customized readObject() and writeObject() methods can be designed to continue to support the original serialized form (even if it would change as a result of the new implementation). This is desireable if the API is far flung and changing the serialized form would break many clients of the API. In this case, even though the serialized form would change by the new implementation, the serialVersionUID will need to remain the same to continue to support the original serialized form.

  • Forced upgrade. If the implementation of a class changes and it is impossible or infeasible to support the original serialized form, changing the serialVersionUID will cause clients of the API to break, thereby forcing clients to be upgraded to use the new serialized form. This may be desireable in certain circumstances (but will force clients to upgrade their code).

It is worth mentioning that if you do not explicitly declare a static final serialVersionUID in your serializable class, the Java environment will automatically compute one for you by applying a complex procedure to the code (that takes into account fields and method signatures).

In short, the serialVersionUID should track with the serialized form that is used rather than the actual class implementation. If you want the serialVersionUID to change automatically whenever the class implementation changes, you can simply omit the explicit declaration of the serialVersionUID (but this may have other negative consequences). The decision to change the serialVersionUID needs to be made explicitly depending on how you want your API to behave when an implementation detail changes.

scottb
  • 9,908
  • 3
  • 40
  • 56
  • Also see [this answer](http://stackoverflow.com/questions/896945/follow-up-instance-control-in-java-without-enum/897170#897170) for a solution on how to avoid many of the issues with Java serialization. – biziclop May 30 '15 at 22:04
  • I agree - why my question :) for us it is during development it would be great so we auto invalidate parts of the dev database. I know a ID generator would have to look at the compiled result and all the superclasses and see if the code to what is called from serializable has changed or the data it references (structure of class) has changed and comparing it to the current value. That said if there was one that worked it would be cool and convenient. – peterk May 31 '15 at 19:37