Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / October 2006

Tip: Looking for answers? Try searching our database.

Automating class serial version numbers

Thread view: 
Simon Brooke - 03 Oct 2006 22:59 GMT
For serialisation to work properly as an object changes through versions we
are advised to provide a serialVersionUID which is a static final long.
I'd like to automate the generation of serialVersionUIDs at compile time.
The value could be based either (preferably) on an ant variable called
PROJECT_VERSION or (less preferred) on the time/date of compilation.

I'm certain someone has done this; I've a nasty feeling that it is (or
should be) a FAQ.

The only solution that springs obviously to mind is for ant to copy the
source files from the source directory to an intermediate temporary
directory, making the substitutions as it does so; and then compile from
the intermediate temporary directory to the build directory. This would
work but is clunky.

Does anyone have a better solution?

Signature

simon@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/

       Hobbit ringleader gives Sauron One in the Eye.

Chris Uppal - 04 Oct 2006 09:44 GMT
> For serialisation to work properly as an object changes through versions
> we are advised to provide a serialVersionUID which is a static final long.
> I'd like to automate the generation of serialVersionUIDs at compile time.
> The value could be based either (preferably) on an ant variable called
> PROJECT_VERSION or (less preferred) on the time/date of compilation.

In general you want the serialVersionUID to stay the same as the class
evolves -- the only time when it should change is when you have made a change
to the object's structure which the serialisation mechanism can't cope with by
itself.  So it's the programmer who should be making such changes, as a very
conscious (and very public, since it will typically affect other code)
decision.

   -- chris
Simon Brooke - 04 Oct 2006 10:32 GMT
>> For serialisation to work properly as an object changes through versions
>> we are advised to provide a serialVersionUID which is a static final
[quoted text clipped - 10 lines]
> very conscious (and very public, since it will typically affect other
> code) decision.

Yup, which is why I want it to get it set from PROJECT_VERSION, which will
change only on API updates. But when the API does change, I'd like all the
serialVersionUIDs to change rather than to have to manually edit currently
245 source files in one project, and 177 in another.

Our version numbers are based on the major-version.minor-version.patch
convention (e.g. 1.10.17) where

* Major version numbers change only with significant architectural change;
* Minor version numbers change with any API change, no matter how small;
* Patch numbers are given to releases which fix bugs only and do not
 involve API changes.

It seems to me to make sense to have the serialVersionUID value based on
the major/minor version numbers in some systematic way, so that in
debugging we can tell immediately just which API version a class relates
to. Doing it on date would be effectively similar, since all classes in
the same release would be compiled in the same build operation on the same
date, and relating a date to a release isn't all that problematic.

Obviously, there will be many classes which don't actually change in any
given new release, and so would be inter-serialisable between releases,
but the maintenance overhead in maintaining and tracking separate
servialVersionUID numbers against API changes seems to me uneconomically
high.

Comments?

Signature

simon@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/
               Ring of great evil
               Small one casts it into flame
               Bringing rise of Men                    ;; gonzoron

Chris Uppal - 04 Oct 2006 11:56 GMT
[me:]
> > In general you want the serialVersionUID to stay the same as the class
> > evolves -- the only time when it should change is when you have made a
[quoted text clipped - 8 lines]
> serialVersionUIDs to change rather than to have to manually edit currently
> 245 source files in one project, and 177 in another.

I'm still not sure that we are thinking about this in the same way.  As a very
silly example,

   class Temperature
   {
       private double    degrees;
       public double    getDegrees() { return degrees; }
       // etc
   }

changing that to:

   class Temperature
   {
       private double degrees;
       /**@deprecated*/ public double getDegrees() { return
getDegreesCentrigrade(); }
       public double getDegreesCentrigrade() { return degrees; }
       public double getDegreesFahrenheiht() { return degrees*9.0/5.0+32.0; }
       // etc
   }

would be a major API change, but does not break serialisation.  OTOH, changing
the original to:

   class Temperature
   {
       private double degreesFahrenheiht;
       public double getDegrees() { return (degreesFahrenheiht-32)*5.0/9.0; }
       // etc
   }

is no API change at all, but /does/ break serialisation.

The only scenario I can think of which respects those facts is if, as Andy has
suggested, you don't ever have serialised objects hanging around at all (maybe
you only use it for RMI, perhaps).  But in that case, there doesn't seem to be
a lot of point to defining serialVersionUID in the first place.  But if you do
need it, then it seems simplest just to have in each serialisable class:

   package my.company;
   import my.company.ProductIDs;

   class SomeClassOrOther
   implements Serializable
   {
       public static final long serialVersionUID
               = ProductIDs.PRODUCT_VERSION_NUMBER;
       //...
   }

and let javac do the work for you...

   -- chris
Andy Dingley - 04 Oct 2006 11:15 GMT
> For serialisation to work properly as an object changes through versions we
> are advised to provide a serialVersionUID which is a static final long.

Why do you need to do this?  Is it to allow deserialization to work
correctly with objects that were serialized from an old implementation
(different ID from current) or merely so that it's checked that objects
have the correct ID  (i.e. objects aren't ever persisted between builds
with different IDs)?

If it's the latter case, then life is much simpler. You never care
_what_ the ID is, just that it's not shared with an old and
incompatible version. If the ID changes and the object hasn't, then
that's OK.  Just embed the Subversion (or CVS etc.)
$LastChangedRevision: $  marker in a suitable constant. Subversion is
smart enough to only update this when the source is changed (not just
timestamp it on every checkin) and even though it'll be updated when
non-significant changes to code are made that didn't affect
serialization, that's no problem -- your system merely needs to check
that all objects of that class are using the _same_ ID.
Simon Brooke - 04 Oct 2006 14:44 GMT
>> For serialisation to work properly as an object changes through versions
>> we are advised to provide a serialVersionUID which is a static final
[quoted text clipped - 5 lines]
> have the correct ID  (i.e. objects aren't ever persisted between builds
> with different IDs)?

Frankly, I /don't/ need to do it, since I don't serialise anything. Which
makes it a bit hard to work out just what the right thing to do is. But
people who use stuff I build may need to; and I'm getting annoyed by too
many whinges from the compiler complaining that I haven't done it.

> If it's the latter case, then life is much simpler. You never care
> _what_ the ID is, just that it's not shared with an old and
> incompatible version. If the ID changes and the object hasn't, then
> that's OK.  Just embed the Subversion (or CVS etc.)
> $LastChangedRevision: $  marker in a suitable constant.

OK, but the value of a revision in CVS is of the form $Revision: 1.3.2.3 $,
which isn't particularly easy to compile systematically into a long.
Still, it's worth looking at as a possibility.

> Subversion is
> smart enough to only update this when the source is changed (not just
> timestamp it on every checkin) and even though it'll be updated when
> non-significant changes to code are made that didn't affect
> serialization, that's no problem -- your system merely needs to check
> that all objects of that class are using the _same_ ID.

Yup. I ought to think seriously about moving to Subversion, but I haven't
got there yet.

Signature

simon@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/
   .::;===r==\  
  /  /___||___\____        
 //==\-  ||-  |  /__\(  MS Windows IS an operating environment.
//____\__||___|_//  \|: C++ IS an object oriented programming language.
  \__/ ~~~~~~~~~ \__/   Citroen 2cv6 IS a four door family saloon.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.