United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6934356 : Vector.writeObject() synchronization risks serialization deadlock

Details
Type:
Bug
Submit Date:
2010-03-12
Status:
Closed
Updated Date:
2011-04-06
Project Name:
JDK
Resolved Date:
2011-04-06
Component:
core-libs
OS:
generic
Sub-Component:
java.util
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Relates:
Relates:
Relates:

Sub Tasks

Description
Synopsis:
=========
This bug report revisits topics previously discussed in 4741471 and 5085747.
A testcase and suggested code change have been provided by a Licensee.

JDK Versions:
=============

This problem exists since JDK 1.4.2, including JDK 7-b85.


Problem Description from Licensee:
==================================

java.util.Vector.writeObject() currently calls ObjectOutputStream.writeObject(Object)
for the (elementData) Object[] held by the Vector object whilst synchronized on
the Vector object.

If the Object[] in the Vector object holds a reference (directly or indirectly) to
that of another Vector object, which itself holds a (direct or indirect) reference
to the first Vector object in its Object[], then there is a possibility of deadlock
during serialization if two threads try to write out each Vector object simultaneously.

Given that the evaluation text in 4741471 implicitly acknowledges that the
synchronization in Hashtable and Vector risk deadlock, and 5085747 was
closed primarily because a testcase had not been provided (which we have
now done), both the sunbugs referred to confirm our assertion that this is
a bona fide bug.

The risk of deadlock may be avoided by:

1) Moving the synchronization from being on the whole writeObject()
   method to being a synchronized block within the method
2) Copying the elementData Object[] within the synchronized block
3) Using the ObjectOutputStream putFields mechanism to specify that
   the Object[] copy be output as the "elementData" field
4) Making the call to ObjectOutputStream.writeFields() outside (i.e.
   subsequent to) the synchronized block

As the fix is in Java code, it is naturally cross (OS) platform.
It is unconditionally fixed in our (Licensee's) current Java 6 code.
_Whilst fixing the functional problem does introduce some small overhead,
the suggested fix proposed I believe represents the most efficient way
of addressing the problem without side-effects._

The user cannot avoid the problem without introducing coarser grained
locking round the data structures, which would defeat the primary reason
for using Hashtable and Vector over HashMap and ArrayList - namely, their
implicit synchronization.

Therefore, given that the user has chosen to use Hashtable and Vector,
it seems to me correct to take the necessary steps to ensure that they
behave in a functionally correct manner.


Testcase:
=========

Testcase is attached to this bug report.


Suggested fix:
=============

      * is, serialize it).  This method is present merely for synchronization.
      * It just calls the default writeObject method.
      */
-    private synchronized void writeObject(java.io.ObjectOutputStream s)
+    private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException
     {
-	s.defaultWriteObject();
+	final java.io.ObjectOutputStream.PutField fields = s.putFields();
+	Object[] data = null;
+	synchronized (this) {
+	    fields.put("capacityIncrement", capacityIncrement);
+	    fields.put("elementCount", elementCount);
+	    final int dataLength = elementData.length;
+	    data = new Object[dataLength];
+	    System.arraycopy(elementData, 0, data, 0, dataLength);
+	}
+	fields.put("elementData", data);
+	s.writeFields();
     }
 }

                                    

Comments
SUGGESTED FIX

See webrev provided by Neil Richards of IBM: http://cr.openjdk.java.net/~mduigou/6934356.3/webrev/
                                     
2011-01-11
EVALUATION

patch provided by IBM
                                     
2011-01-11
PUBLIC COMMENTS

Fix contributed by Neil Richards of IBM UK
                                     
2011-02-15



Hardware and Software, Engineered to Work Together