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

Bad exception handling in ObjectInputStream.readObject0() masks user exceptions

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • 6u29
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.6.0_27"
      Java(TM) SE Runtime Environment (build 1.6.0_27-b07)
      Java HotSpot(TM) Client VM (build 20.2-b06, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 2008 Server x64

      A DESCRIPTION OF THE PROBLEM :
      I have received the following exception in an application that serializes objects over RMI

      java.lang.IllegalStateException: unread block data
        at java.io.ObjectInputStream$BlockDataInputStream.setBlockDataMode(ObjectInputStream.java:2376)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1360)
        at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
        at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
        at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
        at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
        at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)

      By debugging the serialization code I found out that the real cause (in this case a RuntimeException) is masked out due to a bad exception handling in ObjectInputStream.readObject0(). What happens is that the call to readOrdinaryObject in line 1328:

      case TC_OBJECT:
      return checkResolve(readOrdinaryObject(unshared));

      eventually calls ObjectStreamClass.invokeReadObjectNoData() which catches an InvocationTargetException and then calls throwMiscException on the cause. This method then in turn throws that exception. The problem now is that in ObjectInputStream.readObject0() there is a finally block:

              // ...
      } finally {
      depth--;
      bin.setBlockDataMode(oldMode);
      }

      and that the call to ObjectInputStream.setBlockDataMode() also throws an exception because there is still data available (of course, there was an exception that aborted the deserialization!). As a consequence the original RuntimeException that contains the actual reason for the problem is gone!



      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Should be reproducible by implementing readObject() on any Serializable class like that:

        private void readObject(ObjectInputStream is) throws IOException
        {
          throw new RuntimeException("I will get masked out!");
        }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect to receive the original cause and not the "java.lang.IllegalStateException: unread block data".
      ACTUAL -
      Already described above.

      REPRODUCIBILITY :
      This bug can be reproduced always.

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: