RFR: JDK-8068721 - RMI-IIOP communication fails when ConcurrentHashMap is passed to remote method

Mark Sheppard mark.sheppard at oracle.com
Mon Mar 23 21:25:55 UTC 2015


Hi
  please oblige and review the following fix

http://cr.openjdk.java.net/~msheppar/8068721/jdk9/corba/webrev/
http://cr.openjdk.java.net/~msheppar/8068721/jdk9/jdk/webrev/


which addresses the issue in
https://bugs.openjdk.java.net/browse/JDK-8068721

This relates to RMI-IIOP and the interplay between custom marshalling of 
ValueTypes and
the corresponding serialization of a Java class, in this case 
ConcurrentHashMap.

ConcurrentHashMap changed its structure in jdk8 from that used in jdk7.
This resulted in modification to the readObject and writeObject methods,
and in particular, former serial fields were removed, resulting in
writeObject using PutField and readObject using defaultReadObject.
The writeObject invokes the putFields method of an ObjectOutputStream 
multiple times, and assumes
that it will receive the same PutField object instance for each 
invocation. The spec
doesn't endorse this behaviour - but that's what the implementation of 
ObjectOutputStream
provides. However in the case of RMI-IIOP, the OutputStreamHook, a 
subclass of ObjectOutputStream, returns a new instance for each
putFields invocation. Thus, the ConcurrentHashMap writeObject results in 
improper serialization in the context
of RMI-IIOP.
In the unmarshalling flow of ConcurrentHashMap, the readObject now uses 
defaultReadObject rather than GetField
In this call flow the IIOPInputStream attempts to ignore any primitive 
field, in the serialized data, that doesn't
correspond with a reflective field of the object. However, it leaves the 
primitive in the stream.
Thus, in the case of ConcurrentHashMap, which has serialized two 
integers and
an array of Segments (subclass of ReentrantLock), this results in erroneous
deserialization, with a misinterpretation of a value tag in the stream 
as an array length
and an attempt to allocate a very large array ensues, with an exception 
being thrown.

The OutputStreamHook now returns the same instance of PutField allocated 
for each separate call of putFields method.
This highlights a need to tighten up and disambiguate the 
OutputObjectStream spec for putFields.

IIOPInputStream now removes the primitive values from the stream.

regards
Mark



More information about the core-libs-dev mailing list