JDK-7038843 : IIOP serialization fails with NullPointerException when serializing Throwable
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2011-04-22
  • Updated: 2014-10-07
  • Resolved: 2011-06-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b142Fixed
Related Reports
Relates :  
Relates :  
Description
The following tests are currently failing in the TL forest (currenly at jdk7-b139 + changes for b140 and b142).

javax/management/remote/mandatory/loading/MethodResultTest.java
javax/management/remote/mandatory/serverError/JMXServerErrorTest.java

The tests are failing with a NullPointerException with stack traces such as the following:

java.lang.NullPointerException
	at java.util.Hashtable.put(Hashtable.java:432)
	at com.sun.corba.se.impl.io.OutputStreamHook$HookPutFields.put(OutputStreamHook.java:115)
	at java.lang.Throwable.writeObject(Throwable.java:963)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.corba.se.impl.io.IIOPOutputStream.invokeObjectWriter(IIOPOutputStream.java:620)
	at com.sun.corba.se.impl.io.IIOPOutputStream.outputObject(IIOPOutputStream.java:586)
	at com.sun.corba.se.impl.io.IIOPOutputStream.simpleWriteObject(IIOPOutputStream.java:174)
	at com.sun.corba.se.impl.io.ValueHandlerImpl.writeValueInternal(ValueHandlerImpl.java:228)
	at com.sun.corba.se.impl.io.ValueHandlerImpl.writeValueWithVersion(ValueHandlerImpl.java:210)
	at com.sun.corba.se.impl.io.ValueHandlerImpl.writeValue(ValueHandlerImpl.java:150)
	at com.sun.corba.se.impl.encoding.CDROutputStream_1_0.writeRMIIIOPValueType(CDROutputStream_1_0.java:817)
	at com.sun.corba.se.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:866)
	at com.sun.corba.se.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:880)
	at com.sun.corba.se.impl.encoding.CDROutputStream.write_value(CDROutputStream.java:246)
	at com.sun.corba.se.spi.servicecontext.UEInfoServiceContext.writeData(UEInfoServiceContext.java:62)
	at com.sun.corba.se.spi.servicecontext.ServiceContext.write(ServiceContext.java:97)
	at com.sun.corba.se.spi.servicecontext.ServiceContexts.writeMapEntry(ServiceContexts.java:340)
	at com.sun.corba.se.spi.servicecontext.ServiceContexts.writeServiceContextsInOrder(ServiceContexts.java:308)
	at com.sun.corba.se.spi.servicecontext.ServiceContexts.write(ServiceContexts.java:265)
	at com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_2.write(ReplyMessage_1_2.java:192)
	at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.createResponseHelper(CorbaMessageMediatorImpl.java:2217)
	at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.createResponseHelper(CorbaMessageMediatorImpl.java:2180)
	at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.createSystemExceptionResponse(CorbaMessageMediatorImpl.java:2105)
	at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:266)
	at com.sun.corba.se.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1698)
	at com.sun.corba.se.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(SharedCDRClientRequestDispatcherImpl.java:171)
	at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:147)
	at org.omg.CORBA.portable.ObjectImpl._invoke(ObjectImpl.java:475)
	at com.sun.jmx.remote.protocol.iiop.ProxyStub._invoke(Unknown Source)
	at org.omg.stub.javax.management.remote.rmi._RMIConnection_Stub.getAttribute(Unknown Source)
	at javax.management.remote.rmi.RMIConnector$RemoteMBeanServerConnection.getAttribute(RMIConnector.java:901)
	at MethodResultTest.test(MethodResultTest.java:143)
	at MethodResultTest.main(MethodResultTest.java:93)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94)
	at java.lang.Thread.run(Thread.java:722)

Comments
SUGGESTED FIX # HG changeset patch # User darcy # Date 1304038285 25200 # Node ID 6c8ae62463a37cdd0c1ec7300659815cfce1e450 # Parent 67f411052dd66bb4f0cc5820ac8d95245b3a5fa7 7038843: IIOP serialization fails with NullPointerException when serializing Throwable Reviewed-by: dholmes, mchung --- a/src/share/classes/java/lang/Throwable.java Fri Apr 29 00:21:54 2011 +0100 +++ b/src/share/classes/java/lang/Throwable.java Thu Apr 28 17:51:25 2011 -0700 @@ -848,10 +848,9 @@ public class Throwable implements Serial throw new NullPointerException("stackTrace[" + i + "]"); } - if (this.stackTrace == null) // Immutable stack - return; - synchronized (this) { + if (this.stackTrace == null) // Immutable stack + return; this.stackTrace = defensiveCopy; } } @@ -958,18 +957,15 @@ public class Throwable implements Serial // trace field is a valid value indicating the stack trace // should not be set. getOurStackTrace(); - ObjectOutputStream.PutField fields = s.putFields(); - - fields.put("detailMessage", detailMessage); - fields.put("cause", cause); - // Serialize a null stacktrace using the stack trace sentinel. - if (stackTrace == null) - fields.put("stackTrace", SentinelHolder.STACK_TRACE_SENTINEL); - else - fields.put("stackTrace", stackTrace); - fields.put("suppressedExceptions", suppressedExceptions); - - s.writeFields(); + + StackTraceElement[] oldStackTrace = stackTrace; + try { + if (stackTrace == null) + stackTrace = SentinelHolder.STACK_TRACE_SENTINEL; + s.defaultWriteObject(); + } finally { + stackTrace = oldStackTrace; + } } /**
29-04-2011

PUBLIC COMMENTS See http://hg.openjdk.java.net/jdk7/tl/jdk/rev/6c8ae62463a3
29-04-2011

EVALUATION Using the PutFields mechanism rather than defaultWriteObject tickles a bug in IIOP serializaiton where using PutFields vs defaultWriteObject makes an observable difference in behavior. While the root cause is a problem in IIOP serialization, the code in Throwable can be improved by using defaultWriteObject instead of PutFields so that is the approach that will be taken. Separately, the issue in IIOP serialization should be fixed.
28-04-2011