Bug 20169

Summary: Serialization: readResolve does not work
Product: gcc Reporter: Daniel Bonniot <bonniot>
Component: libgcjAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED WONTFIX    
Severity: normal CC: gcc-bugs, java-prs
Priority: P2    
Version: 4.0.0   
Target Milestone: ---   
Host: i386-debian-linux-gnu Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2005-07-24 19:36:35
Bug Depends on: 21785    
Bug Blocks:    

Description Daniel Bonniot 2005-02-23 15:29:37 UTC
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)
Comment 1 Daniel Bonniot 2005-02-26 01:35:04 UTC
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
Comment 2 Daniel Bonniot 2005-03-02 22:11:11 UTC
Submitting the mauve testcases, with a classpath patch on the way.
Comment 3 Andrew Pinski 2005-05-27 01:04:00 UTC
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.
Comment 4 Daniel Bonniot 2005-05-27 09:47:39 UTC
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.
Comment 5 Daniel Bonniot 2005-05-27 15:05:37 UTC
The new behaviour is caused by PR21785, which currently masks this bug.
Comment 6 Tom Tromey 2005-07-24 19:36:33 UTC
Note that this is fixed in Classpath but not in libgcj as
we still have divergences in serialization.
Comment 7 Andrew Pinski 2016-09-30 22:51:38 UTC
Closing as won't fix as libgcj (and the java front-end) has been removed from the trunk.