FULL PRODUCT VERSION :
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
If a Serializable class defines a readResolve method; then if it refines the return type, the serialization machinery will not locate the method.
This could be a serious bug if a class is written expecting common behavior, but a test is not done; in other words:
public final class Foo implements Serializable {
private static final Foo SINGLETON = new Foo();
private Foo() {}
private Object readResolve() { return SINGLETON; }
}
may be considered an "obvious or easy" class or a very simple type; but if the readResolve method is made covariant:
private Foo readResolve() { return SINGLETON; }
then the class will be broken -- serialization will not invoke this readResolve method.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
If a Serializable class defines a readResolve method then it must not refine the return type of the method or the seialization machinery will not invoke the method.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The ability to refine the return type of readResolve.
ACTUAL -
An obscured method signature.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
** There is no indication unless testing is performed.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class SerTest implements Serializable {
private static final SerTest SINGLETON = new SerTest();
public static void main(String[] args) throws Exception {
ByteArrayOutputStream b = new ByteArrayOutputStream();
(new ObjectOutputStream(b)).writeObject(SINGLETON);
SerTest re
= (SerTest) (new ObjectInputStream(
new ByteArrayInputStream(
b.toByteArray()))).readObject();
System.out.println(SINGLETON);
System.out.println(re);
System.out.println(SINGLETON == re);
}
private SerTest() { }
private SerTest readResolve() { return SerTest.SINGLETON; }
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The method cannot be made covariant. And in truth, there may not be very much utility in refining the return type; but I'll add again that it may be very easy to write a broken implementation that only test coverage could uncover -- there is no checked warning or any other indication.