I attach a simple Java class, which exercises the readResolve method. An object is serialzed and deserialized from a byte array. Because of the readResolve method, the object read back should be the exact same instance. This works with JDK, but fails with both gij and gcj, as of today. It also fails with other free runtimes: kaffe (1.1.4.PRECVS8) and jamvm (1.2.3), so it could be a GNU classpath issue. Here is the testcase: /////////////////////////////////// import java.io.*; public abstract class Enum implements Serializable { static Enum instance; Object readResolve() { return instance; } static class Color extends Enum { static final Color red = new Color(); static { instance = red; } } public static void main(String[] args) { try { ByteArrayOutputStream outb = new ByteArrayOutputStream(); ObjectOutputStream outs = new ObjectOutputStream(outb); outs.writeObject(Color.red); byte[] store = outb.toByteArray(); ByteArrayInputStream inb = new ByteArrayInputStream(store); ObjectInputStream ins = new ObjectInputStream(inb); Color color = (Color) ins.readObject(); System.out.println(color); System.out.println(Color.red); System.out.println(color == Color.red); } catch (Throwable e) { throw new Error(e); } } } ////////////////////////////////////// Here is what happens: /tmp/gcc/bin/gcj -C Enum.java #### JDK: java Enum Enum$Color@1cfb549 Enum$Color@1cfb549 true #### GIJ: LD_LIBRARY_PATH=/tmp/gcc/lib /tmp/gcc/bin/gij Enum Enum$Color@58c78 Enum$Color@58eb8 false #### GCJ: /tmp/gcc/bin/gcj --main=Enum *.class LD_LIBRARY_PATH=/tmp/gcc/lib ./a.out Enum$Color@58cd0 Enum$Color@58f20 false /tmp/gcc/bin/gcj --version gcj (GCC) 4.0.0 20050223 (experimental)
After some investigation, I think I understand what is going wrong. It seems like readResolve is only called if it is declared in the deserialized object's class. However, it should also be searched for in the classes's parents, provided the method there is visible (that is, normal rules apply). I submitted a related testcase to mauve: http://sources.redhat.com/ml/mauve-patches/2005/msg00032.html
Submitting the mauve testcases, with a classpath patch on the way.
Hmm, I get: Exception in thread "main" java.lang.Error: java.lang.ClassNotFoundException: Enum$Color at Enum.main (Enum.java:34) Caused by: java.lang.ClassNotFoundException: Enum$Color at java.lang.Class.forName (natClass.cc:91) at java.io.ObjectInputStream.resolveClass (ObjectInputStream.java:782) at java.io.ObjectInputStream.readClassDescriptor (ObjectInputStream.java:534) at java.io.ObjectInputStream.readObject (ObjectInputStream.java:228) at java.io.ObjectInputStream.readObject (ObjectInputStream.java:275) at Enum.main (Enum.java:29) Which looks like a different bug.
FYI, my patch for solving this bug in classpath is https://savannah.gnu.org/patch/index.php?func=detailitem&item_id=3893 My copyright assignment is on its way... I cannot comment on the current behaviour of gcc, as my nightly build seems borked.
The new behaviour is caused by PR21785, which currently masks this bug.
Note that this is fixed in Classpath but not in libgcj as we still have divergences in serialization.
Closing as won't fix as libgcj (and the java front-end) has been removed from the trunk.