The code in ObjectOutputStream and ObjectStreamClass is a little flaky
too, both have non volatile, non final references which my not be
consistent between threads. ObjectStreamClass is first constructed then
initialized, perhaps it's reference is escaping before initialization.
Have you tried making field references in MarshalOutputStream and
MarshalInstanceOutputStream, final or volatile? I suspect the problem
originates in ObjectStreamClass.
It would also appear that the ObjectStreamClass object passed as a
parameter to
java.io.ObjectOutputStream.writeClassDescriptor(ObjectOutputStream.java:664)
is null.
Both stack traces have this method in common, this is where ObjectOutputStream
accesses non a non volatile mutable reference.
java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1269)
java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1274)
There are two method calls in this method, in each case where the stack
trace diverges, but problems could occur because of null references.
It seems the Class associated with the object returned by the
ObjectStreamClass.forClass() is null in one case and in the other
ObjectStreamClass itself is null.
Is this test using FakeRMIClassLoaderSpi? If so, it might not throw a
null pointer exception for RMIClassLoadergetAnnotation(Class cl),
breaking the contract when cl is null.
When ObjectStreamClass.lookup(Class cl) looks up an object, if it
doesn't implement Serializable, it returns null.
ObjectOutputStream.writeObject(Object obj) is final, so we can't
override it, however this is an implementation of ObjectOutput, so we
could use a wrapper class to control synchronization and visibility, not
that I'm recommending it as the solution, we just might need to consider
refactoring so we can regain some control over visibility: "Favour
encapsulation over inheritance."
I'm not really sure if this helps, I'll keep looking I might be wrong ;)
Cheers,
Peter.
Patricia Shanahan (JIRA) wrote:
[ https://issues.apache.org/jira/browse/RIVER-392?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12995444#comment-12995444 ]
Patricia Shanahan commented on RIVER-392:
-----------------------------------------
The RIVER_392_sun1.txt failure appears to be a concurrency issue.
The NullPointerException line is:
locOut.writeObject(loc);
For that line to be the source of a NullPointerException, locOut must be null.
locOut is a private field in MarshalledInstanceOutputStream.
MarshalledInstanceOutputStream has one constructor, which initializes locOut
with the result of an object instantiation, which cannot be null. That is the
only assignment to locOut.
The implication is that that the constructor assignment to locOut did not
happen-before the use in writeAnnotation.
This specific problem could be fixed by making locOut final, but the different
exception in the previous failure suggests it is part of a pattern, not just an
isolated issue.
NullPointerException in test job running
com/sun/jini/test/impl/outrigger/matching/StressTestWithShutdown.td
------------------------------------------------------------------------------------------------------------
Key: RIVER-392
URL: https://issues.apache.org/jira/browse/RIVER-392
Project: River
Issue Type: Bug
Components: com_sun_jini_outrigger
Environment: Ubuntu on a VirtualBox under WindowsXP.
Reporter: Patricia Shanahan
Assignee: Patricia Shanahan
Priority: Minor
Attachments: RIVER_392_sun1.txt, StressTestWithShutdown.td
Repeated running of the new version of
com/sun/jini/test/impl/outrigger/matching/StressTestWithShutdown.td produces a
NullPointerException in the test job about once every 4 hours:
[java] =============================== CALLING RUN()
===============================
[java]
[java] java.lang.NullPointerException
[java] at
java.io.ObjectOutputStream.writeClassDescriptor(ObjectOutputStream.java:664)
[java] at
java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1269)
[java] at
java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1227)
[java] at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1411)
[java] at
java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
[java] at
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
[java] at
com.sun.jini.jeri.internal.runtime.Util.marshalValue(Util.java:176)
[java] at
net.jini.jeri.BasicInvocationHandler.marshalArguments(BasicInvocationHandler.java:1182)
[java] at
net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:778)
[java] at
net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
[java] at
net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
[java] at com.sun.jini.outrigger.$Proxy1.write(Unknown Source)
[java] at
com.sun.jini.outrigger.SpaceProxy2.write(SpaceProxy2.java:296)
[java] at
com.sun.jini.test.impl.outrigger.matching.StressTest$WriteRandomEntryTask.spaceWrite(StressTest.java:582)
[java] at
com.sun.jini.test.impl.outrigger.matching.StressTest$WriteRandomEntryTask.run(StressTest.java:545)
[java] at
com.sun.jini.thread.TaskManager$TaskThread.run(TaskManager.java:331)