Corrections to Chapter 11 of Java I/O, Object Serialization

p. 284: Delete the sentence "The hash() function only depends on the same things the serialization depends on, so making a compatible change won't change the SUID." This isn't true. Also delete the last two sentences on the page ("However, if you do this..." to "become incompatible.") Replace with this new paragraph:
Whether you use a custom SUID or let serialver calculate one for you, you are responsible for deciding when a change to a class is compatible with serialization. The serialver tool does not necessarily generate the same SUID for two compatible but different classes. Only the programmer can decide whether a new SUID is required.
p. 286: The last sentence before Example 11-3 should be changed from "Invocations of the normal ZipFile methods, like entries() or getInputStream() methods, are merely passed along to the zf field java.io." to "Invocations of the normal ZipFile methods, like entries() or getInputStream(), are merely passed along to the ZipFile field zf."

p. 288: In the second paragraph, change "the virtual machine creates a new ZipFile object out of thin air" to "the virtual machine creates a new SerializableZipFile object out of thin air".

p. 288: In the last paragraph change SerializableRandomAccessFile to SerializableZipFile.

p. 289: The second sentence of the first paragraph should read "In this case, you can use ObjectOutputStream's defaultWriteObject() method to write the state of the object, then use ObjectInputStream's defaultReadObject() method to read the state of the object." That is, change the second ObjectOutputStream to ObjectInputStream.

p. 291: In the first paragraph in the Preventing Serialization section, a space is missing after "by throwing a NotSerializableException from writeObject()." In other words, the last two sentences should read

You can prevent an object from being serialized, even though it or one of its superclasses implements Serializable, by throwing a NotSerializableException from writeObject(). NotSerializableException is a subclass of java.io.ObjectStreamException which is itself a kind of IOException:
p. 291: At the bottom of the page, throws new NotSerializableException() should be throw new NotSerializableException() (both times). That is, it should read:

  private void writeObject(ObjectOutputStream out) throws IOException {
    throw new NotSerializableException();
  }

  private void readObject(ObjectInputStream in) throws IOException {
    throw new NotSerializableException();
  }
p. 298: In the last paragraph change "linked list" to "hashtable"

p. 299: Example 11-6, the Person class is pretty solidly broken, and doesn't really do what it claims to do. Here's a much improved version with lots of fixes, and that also includes a main() method for testing:

import java.util.*;
import java.io.*;

public class Person implements Serializable, ObjectInputValidation {

  static Hashtable thePeople = new Hashtable();

  String name;
  String ss;

  public Person(String name, String ss) {
  
    this.name = name;
    this.ss = ss;
    thePeople.put(ss, name);
    
  }

  private void readObject(ObjectInputStream in)
   throws IOException, ClassNotFoundException {

    in.registerValidation(this, 5);
    in.defaultReadObject();

  }

  public void validateObject() throws InvalidObjectException {

    if (thePeople.containsKey(this.ss)) {
      throw new InvalidObjectException(this.name + " already exists");
    }
    else {
      thePeople.put(this.ss, this.name);
    }

  }
  
  public String toString() {
    return this.name + "\t" + this.ss;
  }
  
  public static void main(String[] args) throws IOException, ClassNotFoundException {
  
    Person p1 = new Person("Rusty", "123-45-5678");
    Person p2 = new Person("Beth",  "321-45-5678");
    Person p3 = new Person("David", "453-45-5678");
    Person p4 = new Person("David", "453-45-5678");
  
    Enumeration en = thePeople.elements();
    while (en.hasMoreElements()) {
      System.out.println(en.nextElement());
    }
    
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    ObjectOutputStream oout = new ObjectOutputStream(bout);
    oout.writeObject(p1);
    oout.writeObject(p2);
    oout.writeObject(p3);
    oout.writeObject(p4);
    oout.flush();
    oout.close();
    
    ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
    ObjectInputStream oin = new ObjectInputStream(bin);
    try {
      System.out.println(oin.readObject());
      System.out.println(oin.readObject());
      System.out.println(oin.readObject());
      System.out.println(oin.readObject());
    }
    catch (InvalidObjectException e) {
      System.err.println(e);
    }
    oin.close();

    // now empty the hashtable and try again
    thePeople.clear();
    bin = new ByteArrayInputStream(bout.toByteArray());
    oin = new ObjectInputStream(bin);
    try {
      System.out.println(oin.readObject());
      System.out.println(oin.readObject());
      System.out.println(oin.readObject());
      System.out.println(oin.readObject());
    }
    catch (InvalidObjectException e) {
      System.err.println(e);
    }
    oin.close();
    
    en = thePeople.elements();
    while (en.hasMoreElements()) {
      System.out.println(en.nextElement());
    }    
    
  }
  
}

[ Java I/O Corrections | Java I/O Home Page | Table of Contents | Examples | Order from Amazon ] ]

Copyright 1999, 2005 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified September 9, 2005