Bug 22041 - serialVersionUID [code manipulation]
Summary: serialVersionUID [code manipulation]
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 2.0   Edit
Hardware: All All
: P3 enhancement with 2 votes (vote)
Target Milestone: 3.1   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted
: 43933 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-07-30 11:20 EDT by Eric Jain CLA
Modified: 2005-11-24 10:57 EST (History)
10 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Jain CLA 2002-07-30 11:20:40 EDT
Add option 'Source' -> 'Insert Serial Version UID' to generate the following 
code for a class: 

   static final long serialVersionUID = -1644195090283530719L;
Comment 1 Dirk Baeumer CLA 2002-07-30 13:46:09 EDT
What's about defining a template for this. You can even make the serial id a 
variable.

Claude, do you think we should add this
Comment 2 Claude Knaus CLA 2002-07-31 04:27:28 EDT
If there was a way to compute the current serialVersionUID a template would 
make sense.

Philippe,
is there API to get the serial Version UID from a class file?
Comment 3 Eric Jain CLA 2002-07-31 04:45:38 EDT
java.io.ObjectStreamClass.getSerialVersionUID()
Comment 4 Jed Wesley-Smith CLA 2002-09-05 02:18:47 EDT
Its pretty easy to generate if you have the Class object, without it it would 
be a bit more difficult. With a .class file you just call

int suid = java.io.ObjectStreamClass.lookup(theClass).getSerialVersionUID();

but in order to work properly on a source file you would want it to work with 
the current source in memory and not necessarily built. I would assume that the 
easiest thing might be to compile the current source into a temporary Class 
variable and use that, but I do not know the machinations of the internal 
compiler and if it would allow this...
Comment 5 Philipe Mulet CLA 2003-01-15 05:49:20 EST
The trick is that if the file is modified, this template value would need to be 
updated. I am guessing the best way to achieve this is to do it in a builder 
itself (preJava builder, needing to manually perform the compilation trick).
Comment 6 Ali Murtaza Manji CLA 2003-01-21 11:08:59 EST
Any target release for this?  Any updates, is/will this be fixed in 2.1?

Thanks
Comment 7 Dirk Baeumer CLA 2003-01-21 12:39:37 EST
Currently there are no plans to add this for 2.1, unless we get external help.
Comment 8 Dirk Baeumer CLA 2003-01-21 12:39:58 EST
Postponing > 2.1
Comment 9 Jed Wesley-Smith CLA 2003-02-20 22:45:42 EST
for anyone requiring this now, there is a plugin that does this at 
http://lo.fourrier.nom.fr/ecltools/serialVer.zip by Laurent Fourrier that is 
CPL. It generates the SUID on command, and requires that a .class file has been 
created.


Comment 10 Laurent Fourrier CLA 2003-03-26 09:48:56 EST
Concerning the plugin described above, the main dificulty was to extract the
project classpath from eclipse, in order to load the class (
getSerialVersionUID() need to load the class ).
Why use getSerialVersionUID ? Because it is the easiest method, and as far as I
know, the only garanteed to work equaly well no matter the jvm (the algorithm to
determine the svUID does not seems to be very well documented, and I've read
about difference between sun's and ibm's JVMs.
Concerning the need to change the value at each and every modification, I'm not
so sure, and furthermore, if a serialVersionUID is defined, it is systematically
returned when the class is loaded. So if you need to update the svUID, you need
to delete it, compile, and then recompute it.
Comment 11 Jed Wesley-Smith CLA 2003-03-26 19:17:47 EST
The main point of generating a serialVersionUID is so you don't have a 
different one every time you change the class (that's the default behaviour you 
want to override, although apparently you also get a performance benefit from 
having one already, I don't know how significant it is). There are many cases 
where you may safely serialize between two VMs different versions of the class, 
but as a rule if you change the non-transient, non volatile members, you can 
run in to trouble. The default behaviour includes method sigs in the 
calculation so it is very volatile. A good summary of all this is 
http://jguru.com/faq/view.jsp?EID=5064

to quote:
"If a newer version of a serialized object has to be compatible with an older 
version, it is important that the newer version abides by the rules for 
compatible and incompatible changes.

A compatible change is one that can be made to a new version of the class, 
which still keeps the stream compatible with older versions of the class. 
Examples of compatible changes are: 

* Addition of new fields or classes does not affect serialization, as any new 
data in the stream is simply ignored by older versions. When the instance of an 
older version of the class is deserialized, the newly added field will be set 
to its default value.
* You can field change access modifiers like private, public, protected or 
package as they are not reflected to the serial stream. 
* You can change a transient or static field to a non-transient or non-static 
field, as it is similar to adding a field. 
* You can change the access modifiers for constructors and methods of the 
class. For instance a previously private method can now be made public, an 
instance method can be changed to static, etc. The only exception is that you 
cannot change the default signatures for readObject() and writeObject() if you 
are implementing custom serialization. The serialization process looks at only 
instance data, and not the methods of a class. 

Changes which would render the stream incompatible are:

* Once a class implements the Serializable interface, you cannot later make it 
implement the Externalizable interface, since this will result in the creation 
of an incompatible stream. 
* Deleting fields can cause a problem. Now, when the object is serialized, an 
earlier version of the class would set the old field to its default value since 
nothing was available within the stream. Consequently, this default data may 
lead the newly created object to assume an invalid state. 
* Changing a non-static into static or non-transient into transient is not 
permitted as it is equivalent to deleting fields. 
* You also cannot change the field types within a class, as this would cause a 
failure when attempting to read in the original field into the new field. 
* You cannot alter the position of the class in the class hierarchy. Since the 
fully-qualified class name is written as part of the bytestream, this change 
will result in the creation of an incompatible stream. 
* You cannot change the name of the class or the package it belongs to, as that 
information is written to the stream during serialization."

This information describes behaviour when unserializing from say a persistent 
datastore that maintains serialised versions of a class, a more common 
serialization usage is communication between two VMs, so in fact these rules 
should be considered in both cases for the class (it will be both old and new 
depending on the VM).

Another consideration is that field naming is important to serialization, so 
renaming a field will invalidate serialization (ie. Rename Refactoring should 
trigger a SUID regen).
Comment 12 Dirk Baeumer CLA 2003-10-01 04:18:19 EDT
*** Bug 43933 has been marked as a duplicate of this bug. ***
Comment 13 Jan Ploski CLA 2003-10-13 14:50:04 EDT
I coded my own serialVersionUID plugin using BCEL because Laurent
Fourrier's plugin does not work for me. My plugin does not need to
resolve classes, so classpath issues should be less of a concern.
If anyone is interested:

http://remotejava.dyndns.org/serialver/com.jpl.serialver_1.0.0.zip

The README.txt file contains some notes about the remaining rough edges.

At first, I tried to reproduce the ObjectStreamClass behavior using
the JDT API, but failed due to my inability to determine whether
a class contains a static intializer or not (initialization of
non-final static fields seems to generate <clinit>, which is relevant
in context of the serialVersionUID algorithm).
Comment 14 Ali Murtaza Manji CLA 2003-11-20 13:06:57 EST
Hello,
any updates here, will the proposed fix made be accepted for 3.0?  What's the 
status here?  I have various other users who are looking for this 
functionality as well.

Thanks
Comment 15 Andrea Aime CLA 2004-04-14 09:33:44 EDT
To Jan Polski: your plugin does not seems to be online
anymore. Any hope to find it somewhere?
I need the serial version UID generation... Netbeans had it.
Comment 16 Jed Wesley-Smith CLA 2005-01-06 01:12:58 EST
Eclipse 3.1 M4 serialVersionUID quickfix would seem to resolve this bug
properly. I would say it is now a candidate for Closing, Target 3.1
Comment 17 Dirk Baeumer CLA 2005-01-06 04:44:47 EST
Thanks Jed for the reminder.
Comment 18 Henrik Sundberg CLA 2005-05-24 07:18:42 EDT
(In reply to comment #16)
> Eclipse 3.1 M4 serialVersionUID quickfix would seem to resolve this bug
> properly. I would say it is now a candidate for Closing, Target 3.1


It doesn't seem to work in Eclipse 3.1 M7.
Comment 19 Terry Fountoulakis CLA 2005-06-03 14:06:24 EDT
I noticed, aswell with Eclipse 3.1 M7, I repeatedly got 1L when trying to 
generate a serialVersionUID.
Comment 20 Dirk Baeumer CLA 2005-06-06 03:08:52 EDT
There was a bug in M7 which resulted in generating 1L. This got corrected for RC1.
Comment 21 Maarten Coene CLA 2005-10-04 06:12:39 EDT
Please reopen this RFE...

It is still not possible to generate a serialVersionUID if 
the "serialVersionUID quickfix" is disabled! Can you add an option to the menu 
to insert a serialVersionUID declaration (as originally requested) ?

regards,
Maarten
Comment 22 Lon B CLA 2005-11-23 22:20:58 EST
Version: 3.1.1
Build id: M20050929-0840

Still generates serial version 1L upon quick fix via 'default serial version ID' or 'generated serial version ID'.

Also, I second Maarten Coene comment that a "Source" menu option should exist to create the field.
Comment 23 Martin Aeschlimann CLA 2005-11-24 10:57:54 EST
Please file new specific bugs. Best with reproducible examples.