Download presentation
Presentation is loading. Please wait.
Published byLeslie Webster Modified over 8 years ago
1
Serialization 4: Serializable refresh Review of Java Object Serialization and Relationship with RMI-IIOP June 25, 2002
2
java.io.Serializable ● Order of serialization: top down ● writeObject/readObject ● PutField/GetField ● writeReplace/readResolve ● serialVersionUID ● serialPersistantFields ● defaultWriteObject/defaultReadObject
3
Example 1 // Version 0 public class UserData implements Serializable { private String userName; } Future versions of the class which strive to interoperate must include the original version's serialVersionUID. (JDK/bin/serialver tool) It's also hard to compute and may change depending on compiler sensitivity to inner classes (talk to Bob Scheifler, etc), so putting it in when you define the class in the first place is best. // Better version 0 public class UserData implements Serializable { private static final long serialVersionUID = 8782692418019499275L; private String userName; }
4
// Version 1 public class UserData implements Serializable { private static final long serialVersionUID = 8782692418019499275L; // Fields will be serialized in a special order, not // necessarily order of definition private String userName; private long dateOfBirth; } // Version 2 public class UserData implements Serializable { private static final long serialVersionUID = 8782692418019499275L; private String userName; private long dateOfBirth; private transient String homeTown; private void writeObject(ObjectOutputStream oos) throws IOException { // defaultWriteObject only writes THIS type's data (superclass // and subclass data is written separately by the ObjectOutputStream // in order) oos.defaultWriteObject(); oos.writeUTF(homeTown); } private void readObject(ObjectInputStream ois) throws... { oos.defaultReadObject(); try { homeTown = oos.readUTF(); } catch (Exception ex) { homeTown = "Unknown, USA"; }
5
// Version 3 public class UserData implements Serializable { private static final long serialVersionUID = 8782692418019499275L; private String firstName; private String lastName; private long dateOfBirth; private String homeTown; private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("userName", String.class), new ObjectStreamField("dateOfBirth", Long.TYPE), }; private void writeObject(ObjectOutputStream oos) throws IOException { ObjectOutputStream.PutField fields = oos.putFields(); fields.put("userName", firstName + ' ' + lastName); fields.put("dateOfBirth", dateOfBirth); // Note: Do not wrap primitives oos.writeFields(); oos.writeUTF(homeTown); } private void readObject(ObjectInputStream ois) throws... { ObjectInputStream.GetField fields = ois.readFields(); String userName = (String)fields.get("userName", null); splitIntoFirstNameAndLastName(userName); dateOfBirth = (long)fields.get("dateOfBirth",(long)0); try { homeTown = oos.readUTF(); } catch (Exception ex) { homeTown = "Unknown, USA"; }
6
Evolution Notes ● Lots of rules for compatible/incompatible changes ● Arun built a test of all basic changes including writeObject/readObject, but it took weeks to run, so hasn't been run in a year. About 10 classes were taken as a quick look matrix. ● We haven't tested writeReplace/readResolve very much ● We haven't tested inner classes and inner class evolution ● We haven't tested evolving superclasses very much ● We haven't tested optional data semantics very much ● http://java.sun.com/j2se/1.4/docs/guide/serialization/index.html http://java.sun.com/j2se/1.4/docs/guide/serialization/index.html
7
Evolution & RMI-IIOP ● Java Serialization includes all type information on the wire. RMI- IIOP doesn't, so to handle evolution, must use the callback Codebase object. Some want a new RMI-IIOP stream version in which a TypeCode is sent with the valuetype giving all info. ● Codebase IOR exchanged via SendingContext Runtime service context. ● Codebase "meta" method query results in information represented by a FullValueDescriptor including ValueMembers and TypeCodes which are then used to compare the remote and local versions. ● We have sketchy TypeCode and comparison code
8
CDROutputStream write_value write_value First handles nulls, indirections, IDL ValueBases, IDLEntity types, Strings, and Classes (Strings and Classes are special cases of RMI-IIOP types) if it wasn't one of the above, it must be an RMI-IIOP valuetype: 1. Let the ValueHandler perform a writeReplace 2. Must make sure that if the object is different, it isn't a null, indirection, etc. 3. If ValueHandler says isCustomMarshaled, then make sure to set the chunking bit in the valuetag and start chunking 4. Hand control to ValueHandler's writeValue 5. Stop chunking 6. Write end tag
9
CDRInputStream read_value read_value First handles nulls and indirections. 0. If valuetag indicates chunking was used, must start chunking. 1. Based on repository ID(s) and possible expected type argument, must determine the class that was serialized. 2. Handles WstringValue and Class as special cases 3. Handles IDLEntity types 4. Gives control to ValueHandler to readValue 5. If chunking, should skip over any unread data and process the end tag
10
RMI-IIOP Problems In RMI-IIOP, as in Java Object Serialization, data is serialized from superclass down. However, unlike Java Object Serialization, RMI-IIOP stream format version 1 didn't have any indicators to let the reader know where a superclass's data ended and the next subclass's data began. This was fine unless the superclass had evolved to write optional data. With optional data, even querying the remote FVD won't help - - nothing about the remote class's structure itself can tell you what's on the wire. An unevolved reader would need to be able to skip data until the next class boundary, but there are no class boundaries... all the data is together. Thus, stream format version 2 was born...
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.