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)


Reply via email to