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

Incompatibility: fail read instance of Externalizable class defining writeObject

    XMLWordPrintable

Details

    • Bug
    • Resolution: Duplicate
    • P3
    • None
    • 1.1.6
    • core-libs

    Description

      Problem:

        JVM 1.1.6 and JVM 1.2 deserialize failure.

        An unhandled exception is thrown while reading an instance of an
        Externalizable class that happens to define a writeObject
        method. The instance was written by JVM 1.1.6 or earlier release.
        

      ***************************
      Mail message from David Polk of Athena Design.

      We have discovered a serious serialization bug in JDK 116. As per the
      enclosed note, the SC_BLOCK_DATA and SC_WRITE_METHOD flags in
      ObjectStreamClass use the same bit. This means that any Externalizable
      class that has a writeObject() method will not be able to retrieve itself from the stream.

      I have enclosed a sample class that demonstrates the issue. The class
      will serialize itself correctly under 115, but not 116.

      Also, I have reported the issue on the JavaSoft web site.

      This has broken all of Athena Design's Integer file streams under 1.1.6
      and rendered the distributed (RMI) version of our product unusable under
      1.1.6.

      Needless to say, this poses a serious problem for us. Could you review
      this issue and get back to me with information on how we can work around
      the issue (specifically, how we can read our pre 116 files in 116) and
      how JavaSoft will address the issue.

      Thanks,

      David

      --
      David Pollak, President
      Athena Design, Inc. http://www.athena.com
      Integer: the real-time collaborative spreadsheet component

      Test case submitted by David Polk of Athena Design.
      Modified slightly internally.

      import java.io.*;

      public class BlockDataTest implements Externalizable
      {
        private transient long v1 = 2;
        private transient long v2 = 4;

        private static final int numTest = 100;

        private static final verbose = false;

        public static void main(String argv[])
        {
          BlockDataTest[] sers = new BlockDataTest[numTest];
          int x;

          for (x = 0; x < numTest; x++)
            sers[x] = new BlockDataTest(x);

          try {
            ByteOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);

            oos.writeInt(numTest);

            for (x = 0; x < numTest; x++)
              oos.writeObject(sers[x]);
            oos.close();

            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);

            int n = ois.readInt();

            for (x = 0; x < n; x++) {
              sers[x] = (BlockDataTest) ois.readObject();
              
            }

          } catch (Exception e) {
            System.err.println("Caugnt exception: ");
            e.printStackTrace();
          }
          System.err.println("Done");
        }

        public BlockDataTest()
        {
        }

        public BlockDataTest(int v)
        {
          v1 = v;
          v2 = v * 2;
        }
        
        public void readExternal(ObjectInput in)
        throws IOException, ClassNotFoundException
        {
          try {
      v1 = in.readLong();
      if (verbose) {
      System.out.println("v1=" + v1);
      }
      v2 = in.readLong();
      if (verbose) {
      System.out.println(" v2=" + v2);
      }
          } catch (IOException e) {
      e.printStackTrace();
      throw e;
          }
          if (verbose) {
      System.out.println("v1=" + v1 + " v2=" + v2);
      System.out.println("exit readExternal " + this.toString());
          }
        }

        public void writeExternal(ObjectOutput out)
        throws java.io.IOException
        {
          out.writeLong(v1);
          out.writeLong(v2);
        }

        private void readObject(ObjectInputStream ois)
             throws IOException, ClassNotFoundException
        {
          readExternal(ois);
        }

          /**
           * Commented added by internally.
           * This method is the cause of the regression.
           * The writeObject method is not suppose to be defined
           * for Externalizable classes. It is a bug in JDK 1.1.6 and
           * earlier releases record that an Externalizable class has
           * a private writeObject(ObjectOutputStream) method.
           */
        private void writeObject(ObjectOutputStream oos)
             throws IOException
        {
          writeExternal(oos);
        }
      }

      Attachments

        Issue Links

          Activity

            People

              jfialli Joe Fialli
              jfialli Joe Fialli
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: