You can just add a line like
// pin the serial version ID down so that we can let this class evolve a
bit without code
// blowing up with incompatible class exceptions.
static final long serialVersionUID = -1L;
.. the exact value is not important. The important thing is that
(serialization) compatible classes retain the same value.
You can configure Eclipse to ignore this problem. For Eclipse 3.1:
Window -> Preferences -> Java -> Compiler -> Errors/Warnings ->
Potential programming problems -> Serializable class without
serialVersionUID -> Ignore.
--
Regards,
Roland de Ruiter
` ___ ___
`/__/ w_/ /__/
/ \ /_/ / \
You do not declare Serializable, but you inherit it from Frame.
> But still the IDE is giving the warning:
> The serializable class 'AnyClass' does not declare a static final
> serialVersionUID field of type long.
> This is happening with most of the classes.
> Using QuickFix to generate serialVersionUID for each class does not
> seem to be reasonable.
> Is it necessary?
It is a good idea, provided that you are willing to actually *use* the
mechanism by updating the ID whenever you make a change that introduces
a serialization incompatibility. You SHOULD do this, but if you choose
not to do then IMO it is better to not declare a serialVersionUID at all
than to lie about serial version compatibility.
You may also want to consider whether it is really appropriate to
subclass Frame. Unless you are writing a reusable custom GUI component,
it is far more likely that your classes USE or HAVE Frames than that
they ARE Frames. The distinction is perhaps murkier for GUI components
than for many other kinds of classes, but it is no less important. I do
little GUI programming, but in the little I do, I generally avoid
subclassing the standard components.
--
John Bollinger
jobo...@indiana.edu
>Using QuickFix to generate serialVersionUID for each class does not
>seem to be reasonable.
>Is it necessary?
You want to put in an explicit serialVersionUID with specific value.
Otherwise, every time you sneeze the calculated value will change and
invalidate your serialised datafiles. Manually, you can change the
value only when the structure truly changes. On the other paw, it is
up to you to change it when the layout or names change.
see http://mindprod.com/jgloss/serialization.html
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.
> It is a good idea, provided that you are willing to actually *use* the
> mechanism by updating the ID whenever you make a change that introduces
> a serialization incompatibility. You SHOULD do this, but if you choose
> not to do then IMO it is better to not declare a serialVersionUID at all
> than to lie about serial version compatibility.
You should *not* do this. You should leave the serialVersionUID the same
for all versions of a class and let the serialization code figure out
whether versions are serialization-compatible. If you arrive at a
version which is not, you can then provide read/writeObject methods or a
serialPersistentFields member to overcome the differences. If you just
change the serialVersionUID you have broken compatibility permanently
and one day you will rue the day ...
John C. Bollinger wrote:
>
> It is a good idea, provided that you are willing to actually *use* the
> mechanism by updating the ID whenever you make a change that introduces
> a serialization incompatibility. You SHOULD do this, but if you choose
> not to do then IMO it is better to not declare a serialVersionUID at all
> than to lie about serial version compatibility.
good point. How about people forgetting it? I am working with a client
server application. Both client and server should have the same version,
so versioning is, at least at the moment, no issue. Still, considering
that Sun strongly recommends it, I would prefer to use the
serialVersionUID, at least for the class that really are serialized
(that is, the classes that go over the network). But the main reason is
that I am also having problems when testing the client (built with
Eclipse) that connects to a server (built with Ant/javac). I always get
version mismatch. The only way I can do it is first build with Eclipse
and then with Ant, without cleaning.
Still, people are concerned about using serialVersionUID, because people
might forget to update it when necessary.
Incorrect. Whenever you change a class in a way that breaks the normal
serialization mechanism, you should increase the serialVersionUID of
the class and implement readObject (no need to implement writeObject)
to be able to read objects of both class versions.
If you never change serialVersionUID it wouldn't be needed at all.
/JN
Sorry, seems I'm mistaken :-X. I did some testing and the
serialVersionUID is checked BEFORE readObject in the class is called,
making it impossible to change serialVersionUID if you want to be able
to read old versions of the class. This seems stupid to me, as being
able to read the serialVersionUID from the stream in readObject would
facilitate implementing backward compatible deserialization. Is there a
good reason why the serialVersionUID is checked before readObject is
called?
/JN
If you are attempting to deserialize an object of an earlier class
version into an object of a later class version then it is possible, but
not certain, that you can sensibly patch up the differences with a
readObject() method. Going the other way you are out of luck,
*especially* if you need to pass the same object back to the original
sender. With this degree of uncertainty, it is safer IMO to indeed
require compatible class versions for interoperability. If you have a
requirement for indefinite interversion compatibility then a custom
persistence/exchange mechanism is warranted.
--
John Bollinger
jobo...@indiana.edu
>
>Incorrect. Whenever you change a class in a way that breaks the normal
>serialization mechanism, you should increase the serialVersionUID of
>the class and implement readObject (no need to implement writeObject)
>to be able to read objects of both class versions.
IIRC there is some ability in the standard read object methods to read
a file that is broken. It fishes out the fields it can and zeros
others. I have never used this, but it might be worth looking into a
as way of dealing with changed files layouts.
Thank you. Having the same value for serialVersionUID tells
Serialization either that its own versioning mechanisms are sufficient
or that you have compensated by providing some selection or combination
of readObject(), writeObject(), writeReplace(), readResolve(), or
obhectStreamFields[] so that it will be sufficient.
As John Bollinger says, if you have broken compatibility so badly that
none of this can work you might well want to change the
serialVersionUID, although what I would be doing in this case is
probably to increment the class-name.
While you can configure the compiler to ingore it, I for one think this
is a problem with Java. The problem is that if a class is serializable
then all subclasses are also considered serializable. There is no way to
override that and say that a class is not serializable if a superclass
is serializable. It doesn'e alway make sense for a class to be
serializable just because it extends a class that is.
The real solution is that Java needs to support a Serializable
annotation that has precedence over the Serializable marker interface.
This annotation would have a boolean value that by default is true, but
can be specified as false to handle cases where you don't need
serialization.
--
Dale King
What about the concept that you can use a subclass anywhere you could
have used its ancestor class? This implies that if you subclass a
serializable class, your subclass must also be serializable.
- Oliver
> What about the concept that you can use a subclass anywhere you could
>have used its ancestor class? This implies that if you subclass a
>serializable class, your subclass must also be serializable.
Just to clarify. All interfaces implemented are inherited by all
subclasses, so you can't write a subclass of a Serializable class that
is not marked serializable. Whether it WORKS or not is another matter.
But that doesn't really apply in this case. We are not talking about
changing the API in a subclass violating the Liskov substitution
principle. Serialization is really a property of the exact instance.
Consider a GUI component that shows the output of a connection to some
other piece of hardware. The GUI component that it extends is
serializable, but it doesn't make sense to serialize this subclass
because you really can't serialize the connection itself. You can't
really deserialize it and restore the connection.
This example is somewhat bad because it is one where perhaps composition
should have been used instead of inheritance. But the principle is
valid. You can subclass an object that is serializable adding data that
is not serializable such that it makes no sense to serialize the subclass.
--
Dale King
> This example is somewhat bad because it is one where perhaps composition
> should have been used instead of inheritance. But the principle is
> valid. You can subclass an object that is serializable adding data that
> is not serializable such that it makes no sense to serialize the subclass.
But if you do that then substitutability breaks -- specifically the ability to
use the non-serialisable object as a component within a larger object. Since
you mention composition, it seems worthwhile to emphasise that.
-- chris
I realize now that we are actually in agreement, but that I had misread
your original post. I seemed to have focused on "It doesn't alway make sense
for a class to be serializable just because it extends a class that is." and
rather than interpreting that at a high OO level, I was thinking in terms of
Java semantics, where it DOES make sense because Serializable is an
interface, and so all the subclasses must be serializable if they extend a
parent which is serializable (due to the semantics of interface and
inheritance in Java).
Basically, I think we are in agreement that "making Serializable an
interface" was the wrong approach.
- Oliver