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

ObjectInputStream can swallow exceptions

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 7
    • core-libs

      A DESCRIPTION OF THE REQUEST :
      The readObject0 method within ObjectInputStream has a try {} finally {} block. The finally block calls bin.setBlockDataMode() which can throw an exception, this exception thrown in the finally block can mask any exception previously thrown in the try block making it very hard to identify exceptions thrown in user serialisation (readObject) code.

      The readObject0 method should be restructured to catch/rethrow exceptions in the try block, or to not execute the finally block in the event of a previous exception.

      JUSTIFICATION :
      Masking the exception thrown from within user serialisation code can make debugging serialisation exceptions very difficult. Because not only is the real exception not propagated, but the user serialisation code does not even appear in the stack trace of the exception that is thrown.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Exceptions thrown in user written serialisation code, i.e. readObject() method should be propagated and not swallowed.

        From example, expected stack trace should look something like this:

      Exception in thread "main" java.lang.RuntimeException
      at SerialisationExceptionSwallowExample$Test.readObject(SerialisationExceptionSwallowExample.java:28)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
      at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
      at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
      at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1667)
      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1323)
      at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
      at SerialisationExceptionSwallowExample.main(SerialisationExceptionSwallowExample.java:21)
      ACTUAL -
      Runtime exceptions thrown in user serialisation code (readObject) will be swallowed if the ObjectInputStream#readObject0 throws an IllegalStateException("unread block data") from within ObjectInputStream$BlockDataInputStream#setBlockDataMode called from the finally block

      Stack trace looks like this:

      Exception in thread "main" java.lang.IllegalStateException: unread block data
      at java.io.ObjectInputStream$BlockDataInputStream.setBlockDataMode(ObjectInputStream.java:2377)
      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1361)
      at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1667)
      at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1323)
      at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.io.ObjectInputStream;
      import java.io.ObjectOutputStream;
      import java.io.Serializable;


      public class SerialisationExceptionSwallowExample {

      public static void main(String[] args) throws Exception {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos);

      oos.writeObject(new Test[] { new Test() });
      oos.close();

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

      ois.readObject();
      }

      private static class Test implements Serializable {

      private void readObject(final ObjectInputStream ois) throws IOException, ClassNotFoundException {
      ois.read(); //comment out line to prevent exception swallowing
      throw new RuntimeException();
      }

      private void writeObject(final ObjectOutputStream oos) throws IOException {
      oos.write(1);
      oos.writeShort(2);
      }
      }
      }

      ---------- END SOURCE ----------

            smarks Stuart Marks
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: