
Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
>> I'm trying to resolve some compiler warnings that I've simply ignored for
>> quite a long time. Many of them are pretty obvious but I've come across a
[quoted text clipped - 11 lines]
> concrete classes (okay, difficult for JApplet, but you can limit the
> number of subclasses, Throwable is quite useful too...).
Sorry, I don't follow you. If I want to have the benefit of all the existing
code with JFrame and its parents, how do I get them without subclassing
JFrame?
Also, are you suggesting that in cases where I extend a given Exception, I
extend Throwable instead?
>> Can someone explain what this message is about: what it means, why I get
>> it, and how I can prevent it?
[quoted text clipped - 6 lines]
>
> private static final long serialVersionUID = ...some long number...L;
Why is it better for me to specify my own serialVersionUID than let the
function be applied for me? Obviously, I get a bit more control but I'm not
sure what that buys me in this case?
>> I've read the article about Serializable in the API but most of it goes
>> right over my head. I'm particularly foggy on which value I'm supposed to
[quoted text clipped - 5 lines]
> and that gives the number which would be assigned anyway. If the way the
> class is serialised changes, then so should the serialVersionUID.
What is 'serialver' and how/when do I run it, i.e. is it something I need to
do when I compose the code?
What do you mean by "if the way the class is serialized changes"? What are
the different ways a class can be serialized? Why would the way it is
serialized at one point in time change in the future?
>> I'm also unclear on what Bad Things are going to happen if I don't change
>> my code to prevent this warning.
>
> The Bad Thing is that a change in public attributes of a class may change
> the generated UID, and therefore prevent new code loading older serialised
> data, or vice versa.
"Older serialized data"? Could you please explain this scenario to me? I
would have thought that I was always going to be reading _current_ data, not
"older" data. Older data suggests non-current data, something that was
stored in a file or database perhaps, but has become superseded, like a
former salary.
> The Bad Thing that may happen if you do supply one is that you really do
> change the serialised format, but not the UID. Hence a complete mess when
> it comes to deserialisation.
How would I change the serialised format? Is that something I'd do
consciously? If so, why would I do it? Or does it have the potential to
change on me without any conscious intent on my part, say due to a compiler
change?
> It is a pain if you want a custom exception, say, and have no intention of
> going anywhere near serialization. I guess you could get a revision
> control system to embed a version number in the constant.
As you can probably see from my questions, I'm really quite lost. Perhaps I
need to get a few concepts explained to me before I will understand this
discussion. Can you recommend a place to get those concepts, whatever they
are?
I'm afraid my OO theory is not particularly strong and that may be getting
in the way here....
Rhino
Thomas Hawtin - 11 Dec 2005 21:49 GMT
> Sorry, I don't follow you. If I want to have the benefit of all the existing
> code with JFrame and its parents, how do I get them without subclassing
> JFrame?
JFrame frame = new JFrame();
Sorted.
> Also, are you suggesting that in cases where I extend a given Exception, I
> extend Throwable instead?
No! I used Throwable, as Throwable is the base class of Exception that
implements Serializable.
> Why is it better for me to specify my own serialVersionUID than let the
> function be applied for me? Obviously, I get a bit more control but I'm not
> sure what that buys me in this case?
Just in case the class changes slightly, say an extra method. Then the
UID changes and serialisation interoperability fails.
> What is 'serialver' and how/when do I run it, i.e. is it something I need to
> do when I compose the code?
It's a program in the JDK.
> What do you mean by "if the way the class is serialized changes"? What are
> the different ways a class can be serialized? Why would the way it is
> serialized at one point in time change in the future?
A class can store serialised data as it likes. For instance, you can
store a huge number as an array of bytes. Then you might want to change
to using an array of int. Without code to detect which is which,
deserialising the wrong form will fail. In general you might just get
corrupt data and no exception.
> "Older serialized data"? Could you please explain this scenario to me? I
> would have thought that I was always going to be reading _current_ data, not
> "older" data. Older data suggests non-current data, something that was
> stored in a file or database perhaps, but has become superseded, like a
> former salary.
Data serialised by older classes.
> How would I change the serialised format? Is that something I'd do
> consciously? If so, why would I do it? Or does it have the potential to
> change on me without any conscious intent on my part, say due to a compiler
> change?
Just changing the name of a field would do it.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
Rhino - 12 Dec 2005 00:03 GMT
>> Sorry, I don't follow you. If I want to have the benefit of all the
>> existing code with JFrame and its parents, how do I get them without
[quoted text clipped - 46 lines]
>
> Just changing the name of a field would do it.
I really appreciate your attempt to clarify this issue for me but I'm just
not following you. I'm sure it's my fault, not yours.
I read the article Roedy cited but I still don't see the big picture with
regards to serialization. Maybe Roedy can clear this up for me.... (See my
followup to Roedy if you like.)
Rhino
> When an object is serialised, the class information includes this UID. If
> you choose not to provide one, then a value is derived using some function
[quoted text clipped - 3 lines]
>
> private static final long serialVersionUID = ...some long number...L;
> You can choose anything. Preferably it should not duplicate the number of
> another class.
Why does this matter? So far as I know, there's no chance that a class's
serialVersionUID will be used for a class with a different fully-qualified
name. In fact, when I use serializeable classes (which is rarely) I set
serialVersionUID to 1 originally, and increment it if I ever break
compatibility.
Thomas Hawtin - 12 Dec 2005 02:44 GMT
>>You can choose anything. Preferably it should not duplicate the number of
>>another class.
[quoted text clipped - 4 lines]
> serialVersionUID to 1 originally, and increment it if I ever break
> compatibility.
I believe it is permitted for the deserialised instance to have a
different class name to the one in the stream. The SUIDs must match (and
if it is a mistake then they really shouldn't).
Different serialVersionUIDs may be able to detect renaming issues better.
An implementation may get better performance looking up on SUID before
class name, although clearly not with classes under your scheme.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
Mike Schilling - 12 Dec 2005 02:53 GMT
>>>You can choose anything. Preferably it should not duplicate the number of
>>>another class.
[quoted text clipped - 8 lines]
> different class name to the one in the stream. The SUIDs must match (and
> if it is a mistake then they really shouldn't).
I'd never heard of this, and can't find it in
http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/serialTOC.html.
Can you point to a description of it?
Thomas Hawtin - 12 Dec 2005 03:47 GMT
>>I believe it is permitted for the deserialised instance to have a
>>different class name to the one in the stream. The SUIDs must match (and
[quoted text clipped - 3 lines]
> http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/serialTOC.html.
> Can you point to a description of it?
http://download.java.net/jdk6/docs/api/java/io/ObjectInputStream.html#resolveCla
ss(java.io.ObjectStreamClass)
You might consider subclassing ObjectInputStream cheating.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
Mike Schilling - 12 Dec 2005 05:10 GMT
>>>I believe it is permitted for the deserialised instance to have a
>>>different class name to the one in the stream. The SUIDs must match (and
[quoted text clipped - 7 lines]
>
> You might consider subclassing ObjectInputStream cheating.
I consider it the sign of a far braver man than I :-)
Though the javadoc here says "Load the local class equivalent of the
specified stream class description. Subclasses may implement this method to
allow classes to be fetched from an alternate source." It also calls this
the obverse of ObjectOutputStream.annotateClass(), which says
Subclasses may implement this method to allow class data to be stored in the
stream. By default this method does nothing. The corresponding method in
ObjectInputStream is resolveClass. This method is called exactly once for
each unique class in the stream. The class name and signature will have
already been written to the stream. This method may make free use of the
ObjectOutputStream to save any representation of the class it deems suitable
(for example, the bytes of the class file). The resolveClass method in the
corresponding subclass of ObjectInputStream must read and use any data or
objects written by annotateClass.
So my guess is that this is intended to find the correct version of the
named class rather than to substitute a class of a different name.