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

ClassNotFoundException in skipped objects causes serialization to fail

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.2.0
    • core-libs
    • None
    • beta
    • generic
    • generic
    • Verified

      This bug is closely related to 4312433.

      In the current implementation of serialization, ObjectInputStream has a private
      readObject() method which takes a single boolean parameter "requireLocalClass".
      When this parameter is set to true, the readObject() call should succeed only
      if the class of the object to be deserialized can be resolved locally. If
      requireLocalClass is set to false, then deserialization should succeed even if
      a local class for the object is not found. This facility is used when
      deserializing the values of object fields which have no equivalent in the local
      class, and also when skipping over unread object data originally written by
      class-defined writeObject()/writeExternal() methods. In both of these cases,
      the object is not needed by whatever referenced it, so failure to resolve the
      object's class shouldn't cause deserialization to fail for the referencing
      object.

      Unfortunately, only the immediate skipped object is exempted from the local
      class check. If a ClassNotFoundException is thrown while deserializing objects
      referenced indirectly through the skipped object, deserialization will fail
      even though these sub-objects are not necessary for successful construction of
      the outer object.

      The code attached to this bug report gives a concrete example of the fault
      behavior. In the attached code, the sending VM ("VM 1") defines class A as
      follows:

          class A implements Serializable {
              private static final long serialVersionUID = 0L;
              Object obj;

              A() { obj = new Object[] { new B() }; }
          }

          class B implements Serializable {
          }

      The receiving VM ("VM 2") does not contain a version of class B, and defines
      class A as follows:

          class A implements Serializable {
              private static final long serialVersionUID = 0L;
          }

      When VM 2 attempts to deserialize an instance a of class A sent to it by VM 1,
      it recognizes that the field A.foo is absent in its local version of A.
      Accordingly, it does not require that the class of the object that a.foo
      references (Object[]) be present in the local VM. However, it does still
      require that the classes of objects referenced indirectly through a.foo be
      available. As a result, deserialization of a fails, since the class for B
      cannot be found in VM 2, even though the instance of B isn't actually needed to
      deserialize a.

      A correct solution to this problem must also take into account bug 4312433.
      For example, a naive fix for this bug would be to propagate a
      "requireLocalClass" value of false down the object graph, so that missing
      classes of objects referenced indirectly through a skipped object would not
      cause deserialization to abort. However, if (direct) back references to the
      unresolved objects are deserialized in later calls to readObject(), these later
      calls to readObject() _should_ throw the proper ClassNotFoundExceptions. It
      appears that correctly implementing this behavior will involve stashing
      ClassNotFoundExceptions associated with deserialized objects somewhere (perhaps
      in the wire handle table along with the objects themselves), so they can be
      retrieved and thrown depending on the context in which the unresolved object is
      referenced. Such a fix will most likely require non-trivial changes to the
      internal implementation of ObjectInputStream.


            mwarressunw Michael Warres (Inactive)
            mwarressunw Michael Warres (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: