Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4401613

HashMap calls overrideable method in its readObject when deserializing.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.3.0
    • core-libs
    • beta2
    • sparc
    • solaris_7
    • Verified

      The contrived example below shows that subclassers of HashMap which
      use object serialization can run into a problem whereby HashMap uses
      an overrideable method (put(..)) in its readObject method.

      If the subclass overrrides this method its put method may be called
      before deserialisation has restored the subclass's instance variables.

      See
      http://java.sun.com/j2se/1.3/docs/guide/serialization/spec/input.doc4.html#2971H

      // MSer.java
      import java.io.*;
      import java.util.HashMap;

      public class HMSer extends HashMap {

       int x = -1;

       public HMSer() {
         x = 1;
       }

       public HMSer(int val) {
         x = val;
       }

       public Object put(Object key, Object value) {
          System.out.println("PUT: x="+x);
          if (x==0) {
             throw new IllegalStateException();
          }
          return super.put(key, value);
       }
       
       public static void main(String args[]) {
         HMSer ser1 = new HMSer(99);
         ser1.put("a","b");

         FileInputStream fis;
         FileOutputStream fos;
         ObjectInputStream ois;
         ObjectOutputStream oos;
         try {
             fos = new FileOutputStream("obj.ser");
             oos = new ObjectOutputStream(fos);
             oos.writeObject(ser1);
             oos.close();
             fis = new FileInputStream("obj.ser");
             ois = new ObjectInputStream(fis);
             HMSer ser2 = (HMSer)ois.readObject();
             System.out.println(ser2.x);
         } catch (ClassNotFoundException e) {
         } catch (IOException e) {
         }
       }

      }

      % java HMSer
      PUT: x=99
      PUT: x=0
      Exception in thread "main" java.lang.IllegalStateException
              at HMSer.put(HMSer.java:19)
              at java.util.HashMap.readObject(HashMap.java:841)
              at sun.misc.Unsafe.invokeSpecial(Native Method)
              at sun.misc.ClassReflector.invokeSpecial(ClassReflector.java:376)
              at $ClassReflector1.readObject(Unknown Source)
              at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1585)
              at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1508)
              at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1161)
              at java.io.ObjectInputStream.readObject(ObjectInputStream.java:283)
              at HMSer.main(HMSer.java:39)

      As can be seen X is "0" in the put method when deserializing, which is
      not a normal state for the type.

            jjb Josh Bloch (Inactive)
            prr Philip Race
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: