|
Java
serialization automatically handles class versioning, within limits. If I
understand what you are trying to do, you don't need to write your own
writeObject() and readObject() methods. Class versioning is defined as, a
class can evolve while still permitting the evolved class
to:
1. De-serialize a stream serialized by an older
version of the class, or
2. Serialize an object intended to be de-serialized by an
older version of the class.
As I
said before this works within limits, the limits are you can only change
the class as follows: you can rearrange the existing fields, add new fields, or
change the types of non-primitive fields in type compatible ways (for instance,
change a String to an Object, since a String can be assigned to an
Object).
When
fields are added this is what happens automatically:
1. An object written by an older version of the
class then read by the new version with additional fields, those fields
are set to their defaults values according to their type (either false, 0, or
null).
2. An object written by the new version of
the class then read by an old version of the class without the new
fields, the additional fields are silently ignored.
If
this is what you want to do, just implement Serializable and follow my previous
advice. All of the above is handled automatically without intervention by the
programmer.
Tom
Jordan
Well I have this variable (private static final long
serialVersionUID) in the serialized version. But I can't understand how
can I use it. Maybe likle the (private static
final int version) variable. But then how to get it's
value for already serialized instances in my program. Note - the serialized
objects are stored into a database and they are many... It will be too slow to
run the tool over every instance...
----- Original Message -----
Sent: Monday, August 26, 2002 5:35
PM
Subject: [jdjlist] Re: AW: problem with
serizlization
If you are
Serializing objects you have to learn about the serialVersionUID. It is a
64-bit value that Java's object serialization facility uses to determine
whether a serialized object instance is compatiable with the local class of
the same name. Every serialized object has one whether you specify it or
not. But, you should always specify it. Otherwise practically any change to
the class will result in a java.io.InvalidClassException when trying to read
(unmarshall) a persisted instantance of the previous version of the class.
Furthermore if you don't specify one, the JVM will compute it on the fly;
since this is a expensive computation it significantly degrades the
serialization performance.
You should get in the habit of
always including the following class variable to each class
that is Serializable.
private
static final long serialVersionUID =
-7506063353335561975L;
Where the above number is found using
the java tool "serialver -show" (make sure your classpath is set correctly
before running it). It is also printed in the java.io.InvalidClassException
if the persisted instance being read is not compatiable with the local
class.
Note: if serialver is running while you are making changes to
a class, exit serialver and restart it after you made your last change to
the class and compiled it. Since, serialver loads the class only once, if
you don't restart it will compute serialVersionUID on the original
class.
Tom
Jordan
-----Original Message----- From: Zlatko
Kostadinov [mailto:[EMAIL PROTECTED]] Sent:
Monday, August 26, 2002 7:52 AM To: JDJList Subject: [jdjlist] Re: AW:
problem with serizlization
Yes - this is good desicion.
Thanks! But I already have searialized objects - I forgot to put the
version field, although I had seen this method already :-((
-----
Original Message ----- From: "Lesden, Kim"
<[EMAIL PROTECTED]> To: "JDJList"
<[EMAIL PROTECTED]> Sent: Monday, August 26, 2002 2:45
PM Subject: [jdjlist] AW: problem with serizlization
>
Hello Zlatko, > > a simple way would be to store a version
attribute before you store anything else. That way you can also easily
migrate old data on the fly. I have seen this work very well in C++.
However, if you have lots of data and complex version migrations
(v1->v2, v2->v3, ...) this will cost you lots of extra cpu. (see
sample below) > > Regards > Kim > >
/** > * Version 1: > */ > class A
{ > private static final int version =
1; > private ArrayList data = "new"
ArrayList(); > > private void
writeObject(ObjectOutputStream ous) throws IOException
{ >
out.writeObject(version); >
out.writeObject(data); >
} > > private void
readObject(ObjectInputStream ois) throws IOException, >
ClassNotFoundException
{ > version =
out.readObject(); > if
( 1 == version )
{ > data =
"out.readObject(); >
} > } > } > >
/** > * Version 2: > */ > class A
{ > private static final int version =
2; > private ArrayList data = "new"
ArrayList(); > private String name =
"name"; > > private void
writeObject(ObjectOutputStream ous) throws IOException
{ >
out.writeObject(version); >
out.writeObject(data); >
out.writeObject(name); >
} > > private void
readObject(ObjectInputStream ois) throws IOException, >
ClassNotFoundException
{ > version =
out.readObject(); >
data =
"out.readObject(); > if
(version > 1)
{ > name =
out.readObject(); >
} > else
{ >
/* convert version 1 data to meaningful version 2 or throw exception
*/ >
name = "none"; >
} > } > } > >
/** > * Version 3: > */ > class A
{ > private static final int version =
3; > private ArrayList data = "new"
ArrayList(); > private String name =
"name"; > private int age =
0; > > private void
writeObject(ObjectOutputStream ous) throws IOException
{ >
out.writeObject(version); >
out.writeObject(data); >
out.writeObject(name); >
out.writeObject(age); >
} > > private void
readObject(ObjectInputStream ois) throws IOException, >
ClassNotFoundException
{ > version =
out.readObject(); >
data =
"out.readObject(); > if
(version > 1)
{ > name =
out.readObject(); >
} > else
{ >
/* convert version 1 data to meaningful version 2 or throw exception
*/ >
name = "name"; >
} > if (version >
2) { > age
= out.readObject(); >
} > else
{ >
/* convert version 2 data to meaningful version 3 or throw exception
*/ >
age = 0; >
} > } > } > > >
-----Ursprungliche Nachricht----- > Von: Zlatko Kostadinov [mailto:[EMAIL PROTECTED]] >
Gesendet: Montag, 26. August 2002 13:14 > An: JDJList > Betreff:
[jdjlist] problem with serizlization > > > Hi
guys > > I had serizlized objects in this way: > >
class A { > private ArrayList data = "new"
ArrayList(); > > private void
writeObject(ObjectOutputStream ous) throws IOException
{ >
out.writeObject(data); >
} > > private void
readObject(ObjectInputStream ois) throws IOException, >
ClassNotFoundException
{ > data =
"out.readObject(); > } >
} > > And my program now works with objects of this type. I want
to add new field > in the class so the class will
be > > class A { > private
ArrayList data = "new" ArrayList(); > private
name = "name"; > > private void
writeObject(ObjectOutputStream ous) throws IOException
{ >
out.writeObject(data); >
out.writeObject(name); >
} > > private void
readObject(ObjectInputStream ois) throws IOException, >
ClassNotFoundException
{ > data =
"out.readObject(); > //
here is the problem - how to determine is this an instance of the >
new version or no. >
// must I read the name or not. > } >
} > > Any ideas are wellcome > Regards >
Zlatko > > > To change your JDJList options, please
visit: http://www.sys-con.com/java/list.cfm > >
To change your JDJList options, please visit: http://www.sys-con.com/java/list.cfm >
To
change your JDJList options, please visit: http://www.sys-con.com/java/list.cfm
To
change your JDJList options, please visit:
http://www.sys-con.com/java/list.cfm
THIS TRANSMISSION, INCLUDING ANY ATTACHMENTS OR
FILES,
CONTAINS AIRNET COMMUNICATIONS CORPORATION
CONFIDENTIAL
AND PROPRIETARY INFORMATION WHICH MAY BE
OTHERWISE EXEMPT
FROM DISCLOSURE.
The information is intended to be for the
exclusive use of the individual
or entity named above. If you are not the
intended recipient,
be advised that any disclosure, copying,
distribution or other use
of this information is strictly prohibited. If
you have received this
transmission in error, please notify us by
telephone at 1-321-984-1990 or
by email to [EMAIL PROTECTED] immediately
and do not read, print
or save this information in any manner.
To change your JDJList options, please visit:
http://www.sys-con.com/java/list.cfm
To change your JDJList options, please visit: http://www.sys-con.com/java/list.cfm
THIS TRANSMISSION, INCLUDING ANY ATTACHMENTS OR FILES,
CONTAINS AIRNET COMMUNICATIONS CORPORATION CONFIDENTIAL
AND PROPRIETARY INFORMATION WHICH MAY BE OTHERWISE EXEMPT
FROM DISCLOSURE.
The information is intended to be for the exclusive use of the individual
or entity named above. If you are not the intended recipient,
be advised that any disclosure, copying, distribution or other use
of this information is strictly prohibited. If you have received this
transmission in error, please notify us by telephone at 1-321-984-1990 or
by email to [EMAIL PROTECTED] immediately and do not read, print
or save this information in any manner.
|