-
Bug
-
Resolution: Fixed
-
P4
-
1.3.0
-
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.
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.