CONTENTS | PREV | NEXT
A.6 Guarding Unshared Deserialized Objects
If a class has any private or package private object reference fields, and the class depends on the fact that these object references are not available outside the class (or package), then either the referenced objects must be defensively copied as part of the deserialization process, or else the ObjectOutputStream.writeUnshared and ObjectInputStream.readUnshared methods (introduced in version 1.4 of the Java 2 SDK, Standard Edition) should be used to ensure unique references to the internal objects.In the copying approach, the sub-objects deserialized from the stream should be treated as "untrusted input": newly created objects, initialized to have the same value as the deserialized sub-objects, should be substituted for the sub-objects by the readObject method. For example, suppose an object has a private byte array field, b, that must remain private:
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); b = (byte[])b.clone(); if (<invariants are not satisfied>) throw new java.io.StreamCorruptedException(); }This issue is particularly important when considering serialization of immutable objects containing internal (necessarily private) references to mutable sub-objects. If no special measures are taken to copy the sub-objects during deserialization of the container object, then a malicious party with write access to the serialization stream may violate the container object's immutability by forging references to its mutable sub-objects, and using these references to change the internal state of the container object. Thus, in this case it is imperative that the immutable container class provide a class-specific deserialization method which makes private copies of each mutable component object it deserializes. Note that for the purpose of maintaining immutability, it is unnecessary to copy immutable component objects.It is also important to note that calling clone may not always be the right way to defensively copy a sub-object. If the clone method cannot be counted on to produce an independent copy (and not to "steal" a reference to the copy), an alternative means should be used to produce the copy. An alternative means of copying should always be used if the class of the sub-object is not final, since the clone method or helper methods that it calls may be overridden by subclasses.
Starting in version 1.4 of the Java 2 SDK, Standard Edition, unique references to deserialized objects can also be ensured by using the ObjectOutputStream.writeUnshared and ObjectInputStream.readUnshared methods, thus avoiding the complication, performance costs and memory overhead of defensive copying. The readUnshared and writeUnshared methods are further described in Section 3.1, "The ObjectInputStream Class" and Section 2.1, "The ObjectOutputStream Class".
CONTENTS | PREV | NEXT