You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@river.apache.org by Peter Firmstone <ji...@zeus.net.au> on 2013/04/14 22:16:37 UTC

Indefinite hang - no progress while in loop liveness failure

Gregg,

You are so right, I've just spent the weekend trying to fix an unrelated 
test, fixing one problem reveals another.

The patch (attached) attempts to fix some synchronization issues with 
Mahalo, this patch needs to be applied against qa-refactoring in skunk.

These two tests hang indefinitely:

com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td

com.sun.jini.test.impl.mahalo.PrepareAndCommitExceptionTest4.td  (Thread 
dump for this test appended).

2013-04-15 05:53:48
Full thread dump Java HotSpot(TM) Server VM (20.5-b03 mixed mode):

"RMI TCP Connection(332)-10.1.1.2" daemon prio=3 tid=0x007fd800 nid=0x6a 
runnable [0xb517f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
    - locked <0xe66ec2e0> (a java.io.BufferedInputStream)
    at java.io.FilterInputStream.read(FilterInputStream.java:66)
    at 
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
    at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - <0xe645f1d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

"(JSK) mux request dispatch" daemon prio=3 tid=0x01013000 nid=0x33 
runnable [0xb467d000]
   java.lang.Thread.State: RUNNABLE
    at com.sun.jini.mahalo.AbortJob.computeResult(AbortJob.java:284)
    - locked <0xbb8a2c10> (a com.sun.jini.mahalo.AbortJob)
    at 
com.sun.jini.mahalo.TxnManagerTransaction.abort(TxnManagerTransaction.java:1034)
    - locked <0xbb8a2c60> (a java.lang.Object)
    at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:795)
    at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:754)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at 
net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
    at 
net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
    at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
    at 
net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
    at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
    at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
    at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
    at 
com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
    at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
    at 
com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
    at 
net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
    at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
    at 
com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) mux reader" daemon prio=3 tid=0x01011400 nid=0x32 runnable 
[0xb477f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) mux reader" daemon prio=3 tid=0x005b0400 nid=0x31 runnable 
[0xb487f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) mux writer" daemon prio=3 tid=0x005af400 nid=0x30 in 
Object.wait() [0xb497f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8a6d20> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
    - locked <0xbb8a6d20> (a java.lang.Object)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) mux writer" daemon prio=3 tid=0x005ae000 nid=0x2f in 
Object.wait() [0xb4a7f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8aad00> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
    - locked <0xbb8aad00> (a java.lang.Object)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) ConnectionManager.Reaper" daemon prio=3 tid=0x007ff000 nid=0x2c 
waiting on condition [0xb4d7f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at 
net.jini.jeri.connection.ConnectionManager$Reaper.run(ConnectionManager.java:597)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) mux request dispatch" daemon prio=3 tid=0x006a0800 nid=0x2a in 
Object.wait() [0xb4f7d000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8aaf10> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at 
com.sun.jini.jeri.internal.mux.Session$MuxInputStream.read(Session.java:853)
    - locked <0xbb8aaf10> (a java.lang.Object)
    at 
net.jini.jeri.connection.ConnectionManager$Outbound$Input.read(ConnectionManager.java:550)
    at 
net.jini.jeri.BasicObjectEndpoint.executeCall(BasicObjectEndpoint.java:410)
    at 
net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:806)
    at 
net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
    at 
net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
    at $Proxy0.abort(Unknown Source)
    at com.sun.jini.mahalo.TxnMgrProxy.abort(TxnMgrProxy.java:146)
    at 
net.jini.core.transaction.server.ServerTransaction.abort(ServerTransaction.java:113)
    at 
com.sun.jini.mahalo.TxnManagerTransaction.doAbort(TxnManagerTransaction.java:1134)
    at 
com.sun.jini.mahalo.TxnManagerTransaction.commit(TxnManagerTransaction.java:763)
    at com.sun.jini.mahalo.TxnManagerImpl.commit(TxnManagerImpl.java:712)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at 
net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
    at 
net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
    at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
    at 
net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
    at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
    at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
    at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
    at 
com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
    at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
    at 
com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
    at 
net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
    at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
    at 
com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) mux reader" daemon prio=3 tid=0x003bfc00 nid=0x26 runnable 
[0xb537f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) mux writer" daemon prio=3 tid=0x00984400 nid=0x25 in 
Object.wait() [0xb547f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8bad70> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:485)
    at 
com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
    - locked <0xbb8bad70> (a java.lang.Object)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"event listener notification" daemon prio=3 tid=0x00483000 nid=0x23 in 
Object.wait() [0xb567f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8bb778> (a java.util.LinkedList)
    at java.lang.Object.wait(Object.java:485)
    at 
net.jini.discovery.LookupDiscovery$Notifier.run(LookupDiscovery.java:920)
    - locked <0xbb8bb778> (a java.util.LinkedList)

   Locked ownable synchronizers:
    - None

"multicast announcement timer" daemon prio=3 tid=0x00ade000 nid=0x22 
waiting on condition [0xb577f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at 
net.jini.discovery.LookupDiscovery$AnnouncementTimerThread.run(LookupDiscovery.java:1434)

   Locked ownable synchronizers:
    - None

"multicast discovery announcement listener" daemon prio=3 tid=0x00adcc00 
nid=0x21 runnable [0xb587f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainDatagramSocketImpl.peekData(Native Method)
    - locked <0xbb8bdab8> (a java.net.PlainDatagramSocketImpl)
    at java.net.DatagramSocket.receive(DatagramSocket.java:675)
    - locked <0xbb8bfae8> (a java.net.DatagramPacket)
    - locked <0xbb8bda80> (a java.net.MulticastSocket)
    at 
net.jini.discovery.LookupDiscovery$AnnouncementListener.run(LookupDiscovery.java:1205)

   Locked ownable synchronizers:
    - None

"settleThread" daemon prio=3 tid=0x00669c00 nid=0x1e in Object.wait() 
[0xb5b7f000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
    at 
com.sun.jini.mahalo.TxnManagerImpl.settleTxns(TxnManagerImpl.java:885)
    - locked <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
    at 
com.sun.jini.mahalo.TxnManagerImpl.access$100(TxnManagerImpl.java:117)
    at com.sun.jini.mahalo.TxnManagerImpl$2.run(TxnManagerImpl.java:331)

   Locked ownable synchronizers:
    - None

"(JSK) KeepAlive" prio=3 tid=0x005cc800 nid=0x1d waiting on condition 
[0xb5c7f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at 
com.sun.jini.jeri.internal.runtime.JvmLifeSupport$2.run(JvmLifeSupport.java:133)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) Reaper" daemon prio=3 tid=0x005cc000 nid=0x1c in Object.wait() 
[0xb5d7f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
    - locked <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
    at 
com.sun.jini.jeri.internal.runtime.ImplRefManager$Reaper.run(ImplRefManager.java:426)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"(JSK) 
TcpServerEndpoint.LH[ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=36713]] 
accept loop" daemon prio=3 tid=0x005ce400 nid=0x1b runnable [0xb5e7f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
    - locked <0xbb8b8708> (a java.net.SocksSocketImpl)
    at java.net.ServerSocket.implAccept(ServerSocket.java:462)
    at java.net.ServerSocket.accept(ServerSocket.java:430)
    at 
net.jini.jeri.tcp.TcpServerEndpoint$LH.executeAcceptLoop(TcpServerEndpoint.java:797)
    at 
net.jini.jeri.tcp.TcpServerEndpoint$LH.access$400(TcpServerEndpoint.java:735)
    at 
net.jini.jeri.tcp.TcpServerEndpoint$LH$1.run(TcpServerEndpoint.java:767)
    at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
    at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"RMI TCP Connection(331)-10.1.1.2" daemon prio=3 tid=0x003a8c00 nid=0x1a 
runnable [0xb5f7f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
    - locked <0xe66b5280> (a java.io.BufferedInputStream)
    at java.io.FilterInputStream.read(FilterInputStream.java:66)
    at 
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
    at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - <0xbb8c0420> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

"JMX server connection timeout 18" daemon prio=3 tid=0x005cf800 nid=0x19 
in Object.wait() [0xb607f000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8c0718> (a [I)
    at 
com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150)
    - locked <0xbb8c0718> (a [I)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"RMI Scheduler(0)" daemon prio=3 tid=0x005d1400 nid=0x18 waiting on 
condition [0xb617f000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0xbb8a2178> (a 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at 
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
    at 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
    at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
    at 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
    at 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
    at 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"DestroyJavaVM" prio=3 tid=0x00031800 nid=0x2 waiting on condition 
[0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

"Thread-1" prio=3 tid=0x004be800 nid=0x17 runnable [0xb627f000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0xbb8c0cd0> (a 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at 
java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
    at 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
    at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
    at 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
    at 
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
    at 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
    at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"GC Daemon" daemon prio=3 tid=0x0052dc00 nid=0x15 in Object.wait() 
[0xb647f000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb8076b8> (a sun.misc.GC$LatencyLock)
    at sun.misc.GC$Daemon.run(GC.java:100)
    - locked <0xbb8076b8> (a sun.misc.GC$LatencyLock)

   Locked ownable synchronizers:
    - None

"RMI Reaper" prio=3 tid=0x00529800 nid=0x14 in Object.wait() [0xb657f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
    - locked <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
    at sun.rmi.transport.ObjectTable$Reaper.run(ObjectTable.java:333)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"RMI TCP Accept-0" daemon prio=3 tid=0x002f5400 nid=0x13 runnable 
[0xb667f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
    - locked <0xbb8001a8> (a java.net.SocksSocketImpl)
    at java.net.ServerSocket.implAccept(ServerSocket.java:462)
    at java.net.ServerSocket.accept(ServerSocket.java:430)
    at 
sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
    at 
sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"RMI TCP Accept-0" daemon prio=3 tid=0x002f4c00 nid=0x12 runnable 
[0xb677f000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
    - locked <0xbb803c98> (a java.net.SocksSocketImpl)
    at java.net.ServerSocket.implAccept(ServerSocket.java:462)
    at java.net.ServerSocket.accept(ServerSocket.java:430)
    at 
sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:34)
    at 
sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
    at 
sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
    at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
    - None

"Attach Listener" daemon prio=3 tid=0x0020ac00 nid=0xf waiting on 
condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

"Low Memory Detector" daemon prio=3 tid=0x00124000 nid=0xd runnable 
[0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

"C2 CompilerThread1" daemon prio=3 tid=0x00121000 nid=0xc waiting on 
condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

"C2 CompilerThread0" daemon prio=3 tid=0x0011ec00 nid=0xb waiting on 
condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

"Signal Dispatcher" daemon prio=3 tid=0x0011d000 nid=0xa runnable 
[0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None

"Finalizer" daemon prio=3 tid=0x0010c800 nid=0x9 in Object.wait() 
[0xb707f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
    - locked <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

   Locked ownable synchronizers:
    - None

"Reference Handler" daemon prio=3 tid=0x00107c00 nid=0x8 in 
Object.wait() [0xb717f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0xbb804090> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:485)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
    - locked <0xbb804090> (a java.lang.ref.Reference$Lock)

   Locked ownable synchronizers:
    - None

"VM Thread" prio=3 tid=0x00104000 nid=0x7 runnable

"GC task thread#0 (ParallelGC)" prio=3 tid=0x00039000 nid=0x3 runnable

"GC task thread#1 (ParallelGC)" prio=3 tid=0x0003a800 nid=0x4 runnable

"GC task thread#2 (ParallelGC)" prio=3 tid=0x0003bc00 nid=0x5 runnable

"GC task thread#3 (ParallelGC)" prio=3 tid=0x0003d000 nid=0x6 runnable

"VM Periodic Task Thread" prio=3 tid=0x00136000 nid=0xe waiting on 
condition

JNI global references: 1404


Re: Indefinite hang - no progress while in loop liveness failure

Posted by Peter Firmstone <ji...@zeus.net.au>.
Thanks Gregg,

It turned out to be an endless loop with a swallowed OME.

I've noticed there are some places where we catch and ignore Throwable, 
I had another problem earlier with an index out of bounds exception, 
again a swallowed Throwable made it much harder to debug.

The latest commit includes lots of final fields, additional 
synchronization where it was missed and less locking in some places 
(using AtomicInteger, AtomicArray, ConcurrentHashMap and a volatile 
reference) where I suspected the racy behaviour was chosen to avoid 
deadlock.

I've also removed Thread.start() calls from constructors.

Seem to be having much more success now, locally at least.

So I've cleaned up Mahalo, Outrigger and Mercury.

There's a new Starter interface for starting services after 
construction, this is easy to implement, all you need to implement 
Starter is one start() method and the rest is done for you.

The other service implementations still have threads starting in their 
constructors.

I'm not sure whether to go all the way and fix these too, at least if I 
do, development following River 2.3.0 will be far less brittle, at the 
moment most of my time is spent chasing concurrency bugs, rather than 
actual development I'd like to be doing.

On the plus side, the new ConcurrentPolicyFile policy provider is so 
fast, it's share of the system load is about 0.1% or less now.

DynamicPolicyProvider has the same semantics as before (grants made to 
ClassLoader), but ConcurrentPolicyFile grants are made to URI, not URL, 
people wanting strict compatibility can still use sun's PolicyFile, yet 
still have the benefits of dynamic runtime PermissionCollection sorting, 
so they don't have to put the most often checked Permission's at the end 
of their policy files, this is done for them at runtime.

Cheers,

Peter.

On 16/04/2013 1:37 AM, Gregg Wonderly wrote:
> Okay, I just went back to look again, and I do see a synchronized(this) that I missed.  So that might not be the real issue.  but, at any rate, the computeResult:284 location looks like a mysterious place for the stack trace to reveal.  Typically, threads have to spend a lot of time at a place on the stack, like this, for the thread dump to catch it there.  The largest latency spots are often what you see in these dumps.
>
> Gregg
>
> On Apr 15, 2013, at 10:29 AM, Gregg Wonderly<gr...@wonderly.org>  wrote:
>
>> Let me be more specific.  There are many "logic elimination" optimizations in the hit these days.  For non-volatile and unsynchronized access to "class variables", the JIT will make the assessment that because you don't both read and write the variable in the method, that the value will never change, and thus it will read it only once, and do some things such as loop test hoisting.  I haven't had a chance yet to see what code this method generates, but I would almost bet, that something happens in here that eliminates the tests.
>>
>> Gregg
>>
>> On Apr 14, 2013, at 7:53 PM, Gregg Wonderly<ge...@cox.net>  wrote:
>>
>>> Because pending is accessed in that method (isCompleted), and it is non-volatile, and the method is not synchronized, all bets are off on predictable behavior.
>>>
>>> Gregg Wonderly
>>>
>>> On Apr 14, 2013, at 3:16 PM, Peter Firmstone<ji...@zeus.net.au>  wrote:
>>>
>>>> Gregg,
>>>>
>>>> You are so right, I've just spent the weekend trying to fix an unrelated test, fixing one problem reveals another.
>>>>
>>>> The patch (attached) attempts to fix some synchronization issues with Mahalo, this patch needs to be applied against qa-refactoring in skunk.
>>>>
>>>> These two tests hang indefinitely:
>>>>
>>>> com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
>>>>
>>>> com.sun.jini.test.impl.mahalo.PrepareAndCommitExceptionTest4.td  (Thread dump for this test appended).
>>>>
>>>> 2013-04-15 05:53:48
>>>> Full thread dump Java HotSpot(TM) Server VM (20.5-b03 mixed mode):
>>>>
>>>> "RMI TCP Connection(332)-10.1.1.2" daemon prio=3 tid=0x007fd800 nid=0x6a runnable [0xb517f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>>> at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>>>> at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>>>> - locked<0xe66ec2e0>  (a java.io.BufferedInputStream)
>>>> at java.io.FilterInputStream.read(FilterInputStream.java:66)
>>>> at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>>>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> -<0xe645f1d8>  (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
>>>>
>>>> "(JSK) mux request dispatch" daemon prio=3 tid=0x01013000 nid=0x33 runnable [0xb467d000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at com.sun.jini.mahalo.AbortJob.computeResult(AbortJob.java:284)
>>>> - locked<0xbb8a2c10>  (a com.sun.jini.mahalo.AbortJob)
>>>> at com.sun.jini.mahalo.TxnManagerTransaction.abort(TxnManagerTransaction.java:1034)
>>>> - locked<0xbb8a2c60>  (a java.lang.Object)
>>>> at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:795)
>>>> at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:754)
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>> at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>>>> at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>>>> at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>>>> at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>>>> at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>>>> at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>>>> at java.security.AccessController.doPrivileged(Native Method)
>>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>>>> at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>>>> at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>>>> at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>>>> at java.security.AccessController.doPrivileged(Native Method)
>>>> at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) mux reader" daemon prio=3 tid=0x01011400 nid=0x32 runnable [0xb477f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) mux reader" daemon prio=3 tid=0x005b0400 nid=0x31 runnable [0xb487f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) mux writer" daemon prio=3 tid=0x005af400 nid=0x30 in Object.wait() [0xb497f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8a6d20>  (a java.lang.Object)
>>>> at java.lang.Object.wait(Object.java:485)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>>> - locked<0xbb8a6d20>  (a java.lang.Object)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) mux writer" daemon prio=3 tid=0x005ae000 nid=0x2f in Object.wait() [0xb4a7f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8aad00>  (a java.lang.Object)
>>>> at java.lang.Object.wait(Object.java:485)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>>> - locked<0xbb8aad00>  (a java.lang.Object)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) ConnectionManager.Reaper" daemon prio=3 tid=0x007ff000 nid=0x2c waiting on condition [0xb4d7f000]
>>>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>>> at java.lang.Thread.sleep(Native Method)
>>>> at net.jini.jeri.connection.ConnectionManager$Reaper.run(ConnectionManager.java:597)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) mux request dispatch" daemon prio=3 tid=0x006a0800 nid=0x2a in Object.wait() [0xb4f7d000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8aaf10>  (a java.lang.Object)
>>>> at java.lang.Object.wait(Object.java:485)
>>>> at com.sun.jini.jeri.internal.mux.Session$MuxInputStream.read(Session.java:853)
>>>> - locked<0xbb8aaf10>  (a java.lang.Object)
>>>> at net.jini.jeri.connection.ConnectionManager$Outbound$Input.read(ConnectionManager.java:550)
>>>> at net.jini.jeri.BasicObjectEndpoint.executeCall(BasicObjectEndpoint.java:410)
>>>> at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:806)
>>>> at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
>>>> at net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
>>>> at $Proxy0.abort(Unknown Source)
>>>> at com.sun.jini.mahalo.TxnMgrProxy.abort(TxnMgrProxy.java:146)
>>>> at net.jini.core.transaction.server.ServerTransaction.abort(ServerTransaction.java:113)
>>>> at com.sun.jini.mahalo.TxnManagerTransaction.doAbort(TxnManagerTransaction.java:1134)
>>>> at com.sun.jini.mahalo.TxnManagerTransaction.commit(TxnManagerTransaction.java:763)
>>>> at com.sun.jini.mahalo.TxnManagerImpl.commit(TxnManagerImpl.java:712)
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>> at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>>>> at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>>>> at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>>>> at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>>>> at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>>>> at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>>>> at java.security.AccessController.doPrivileged(Native Method)
>>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>>>> at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>>>> at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>>>> at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>>>> at java.security.AccessController.doPrivileged(Native Method)
>>>> at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) mux reader" daemon prio=3 tid=0x003bfc00 nid=0x26 runnable [0xb537f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) mux writer" daemon prio=3 tid=0x00984400 nid=0x25 in Object.wait() [0xb547f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8bad70>  (a java.lang.Object)
>>>> at java.lang.Object.wait(Object.java:485)
>>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>>> - locked<0xbb8bad70>  (a java.lang.Object)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "event listener notification" daemon prio=3 tid=0x00483000 nid=0x23 in Object.wait() [0xb567f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8bb778>  (a java.util.LinkedList)
>>>> at java.lang.Object.wait(Object.java:485)
>>>> at net.jini.discovery.LookupDiscovery$Notifier.run(LookupDiscovery.java:920)
>>>> - locked<0xbb8bb778>  (a java.util.LinkedList)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "multicast announcement timer" daemon prio=3 tid=0x00ade000 nid=0x22 waiting on condition [0xb577f000]
>>>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>>> at java.lang.Thread.sleep(Native Method)
>>>> at net.jini.discovery.LookupDiscovery$AnnouncementTimerThread.run(LookupDiscovery.java:1434)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "multicast discovery announcement listener" daemon prio=3 tid=0x00adcc00 nid=0x21 runnable [0xb587f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.PlainDatagramSocketImpl.peekData(Native Method)
>>>> - locked<0xbb8bdab8>  (a java.net.PlainDatagramSocketImpl)
>>>> at java.net.DatagramSocket.receive(DatagramSocket.java:675)
>>>> - locked<0xbb8bfae8>  (a java.net.DatagramPacket)
>>>> - locked<0xbb8bda80>  (a java.net.MulticastSocket)
>>>> at net.jini.discovery.LookupDiscovery$AnnouncementListener.run(LookupDiscovery.java:1205)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "settleThread" daemon prio=3 tid=0x00669c00 nid=0x1e in Object.wait() [0xb5b7f000]
>>>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8a2b38>  (a com.sun.jini.mahalo.TransientMahaloImpl)
>>>> at com.sun.jini.mahalo.TxnManagerImpl.settleTxns(TxnManagerImpl.java:885)
>>>> - locked<0xbb8a2b38>  (a com.sun.jini.mahalo.TransientMahaloImpl)
>>>> at com.sun.jini.mahalo.TxnManagerImpl.access$100(TxnManagerImpl.java:117)
>>>> at com.sun.jini.mahalo.TxnManagerImpl$2.run(TxnManagerImpl.java:331)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) KeepAlive" prio=3 tid=0x005cc800 nid=0x1d waiting on condition [0xb5c7f000]
>>>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>>> at java.lang.Thread.sleep(Native Method)
>>>> at com.sun.jini.jeri.internal.runtime.JvmLifeSupport$2.run(JvmLifeSupport.java:133)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) Reaper" daemon prio=3 tid=0x005cc000 nid=0x1c in Object.wait() [0xb5d7f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8a7548>  (a java.lang.ref.ReferenceQueue$Lock)
>>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>>> - locked<0xbb8a7548>  (a java.lang.ref.ReferenceQueue$Lock)
>>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>>> at com.sun.jini.jeri.internal.runtime.ImplRefManager$Reaper.run(ImplRefManager.java:426)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "(JSK) TcpServerEndpoint.LH[ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=36713]] accept loop" daemon prio=3 tid=0x005ce400 nid=0x1b runnable [0xb5e7f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.PlainSocketImpl.socketAccept(Native Method)
>>>> at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>>> - locked<0xbb8b8708>  (a java.net.SocksSocketImpl)
>>>> at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>>> at java.net.ServerSocket.accept(ServerSocket.java:430)
>>>> at net.jini.jeri.tcp.TcpServerEndpoint$LH.executeAcceptLoop(TcpServerEndpoint.java:797)
>>>> at net.jini.jeri.tcp.TcpServerEndpoint$LH.access$400(TcpServerEndpoint.java:735)
>>>> at net.jini.jeri.tcp.TcpServerEndpoint$LH$1.run(TcpServerEndpoint.java:767)
>>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "RMI TCP Connection(331)-10.1.1.2" daemon prio=3 tid=0x003a8c00 nid=0x1a runnable [0xb5f7f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>>> at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>>>> at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>>>> - locked<0xe66b5280>  (a java.io.BufferedInputStream)
>>>> at java.io.FilterInputStream.read(FilterInputStream.java:66)
>>>> at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>>>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> -<0xbb8c0420>  (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
>>>>
>>>> "JMX server connection timeout 18" daemon prio=3 tid=0x005cf800 nid=0x19 in Object.wait() [0xb607f000]
>>>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8c0718>  (a [I)
>>>> at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150)
>>>> - locked<0xbb8c0718>  (a [I)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "RMI Scheduler(0)" daemon prio=3 tid=0x005d1400 nid=0x18 waiting on condition [0xb617f000]
>>>> java.lang.Thread.State: TIMED_WAITING (parking)
>>>> at sun.misc.Unsafe.park(Native Method)
>>>> - parking to wait for<0xbb8a2178>  (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>>>> at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>>>> at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>>>> at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>>>> at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "DestroyJavaVM" prio=3 tid=0x00031800 nid=0x2 waiting on condition [0x00000000]
>>>> java.lang.Thread.State: RUNNABLE
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "Thread-1" prio=3 tid=0x004be800 nid=0x17 runnable [0xb627f000]
>>>> java.lang.Thread.State: TIMED_WAITING (parking)
>>>> at sun.misc.Unsafe.park(Native Method)
>>>> - parking to wait for<0xbb8c0cd0>  (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>>>> at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>>>> at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>>>> at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>>>> at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "GC Daemon" daemon prio=3 tid=0x0052dc00 nid=0x15 in Object.wait() [0xb647f000]
>>>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb8076b8>  (a sun.misc.GC$LatencyLock)
>>>> at sun.misc.GC$Daemon.run(GC.java:100)
>>>> - locked<0xbb8076b8>  (a sun.misc.GC$LatencyLock)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "RMI Reaper" prio=3 tid=0x00529800 nid=0x14 in Object.wait() [0xb657f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb800100>  (a java.lang.ref.ReferenceQueue$Lock)
>>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>>> - locked<0xbb800100>  (a java.lang.ref.ReferenceQueue$Lock)
>>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>>> at sun.rmi.transport.ObjectTable$Reaper.run(ObjectTable.java:333)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "RMI TCP Accept-0" daemon prio=3 tid=0x002f5400 nid=0x13 runnable [0xb667f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.PlainSocketImpl.socketAccept(Native Method)
>>>> at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>>> - locked<0xbb8001a8>  (a java.net.SocksSocketImpl)
>>>> at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>>> at java.net.ServerSocket.accept(ServerSocket.java:430)
>>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "RMI TCP Accept-0" daemon prio=3 tid=0x002f4c00 nid=0x12 runnable [0xb677f000]
>>>> java.lang.Thread.State: RUNNABLE
>>>> at java.net.PlainSocketImpl.socketAccept(Native Method)
>>>> at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>>> - locked<0xbb803c98>  (a java.net.SocksSocketImpl)
>>>> at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>>> at java.net.ServerSocket.accept(ServerSocket.java:430)
>>>> at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:34)
>>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>>>> at java.lang.Thread.run(Thread.java:662)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "Attach Listener" daemon prio=3 tid=0x0020ac00 nid=0xf waiting on condition [0x00000000]
>>>> java.lang.Thread.State: RUNNABLE
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "Low Memory Detector" daemon prio=3 tid=0x00124000 nid=0xd runnable [0x00000000]
>>>> java.lang.Thread.State: RUNNABLE
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "C2 CompilerThread1" daemon prio=3 tid=0x00121000 nid=0xc waiting on condition [0x00000000]
>>>> java.lang.Thread.State: RUNNABLE
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "C2 CompilerThread0" daemon prio=3 tid=0x0011ec00 nid=0xb waiting on condition [0x00000000]
>>>> java.lang.Thread.State: RUNNABLE
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "Signal Dispatcher" daemon prio=3 tid=0x0011d000 nid=0xa runnable [0x00000000]
>>>> java.lang.Thread.State: RUNNABLE
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "Finalizer" daemon prio=3 tid=0x0010c800 nid=0x9 in Object.wait() [0xb707f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb804000>  (a java.lang.ref.ReferenceQueue$Lock)
>>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>>> - locked<0xbb804000>  (a java.lang.ref.ReferenceQueue$Lock)
>>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>>> at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "Reference Handler" daemon prio=3 tid=0x00107c00 nid=0x8 in Object.wait() [0xb717f000]
>>>> java.lang.Thread.State: WAITING (on object monitor)
>>>> at java.lang.Object.wait(Native Method)
>>>> - waiting on<0xbb804090>  (a java.lang.ref.Reference$Lock)
>>>> at java.lang.Object.wait(Object.java:485)
>>>> at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
>>>> - locked<0xbb804090>  (a java.lang.ref.Reference$Lock)
>>>>
>>>> Locked ownable synchronizers:
>>>> - None
>>>>
>>>> "VM Thread" prio=3 tid=0x00104000 nid=0x7 runnable
>>>>
>>>> "GC task thread#0 (ParallelGC)" prio=3 tid=0x00039000 nid=0x3 runnable
>>>>
>>>> "GC task thread#1 (ParallelGC)" prio=3 tid=0x0003a800 nid=0x4 runnable
>>>>
>>>> "GC task thread#2 (ParallelGC)" prio=3 tid=0x0003bc00 nid=0x5 runnable
>>>>
>>>> "GC task thread#3 (ParallelGC)" prio=3 tid=0x0003d000 nid=0x6 runnable
>>>>
>>>> "VM Periodic Task Thread" prio=3 tid=0x00136000 nid=0xe waiting on condition
>>>>
>>>> JNI global references: 1404
>>>>
>>>> # This patch file was generated by NetBeans IDE
>>>> # Following Index: paths are relative to: /opt/src/River_Fixed/peterConcurrentPolicy
>>>> # This patch can be applied using context Tools: Patch action on respective folder.
>>>> # It uses platform neutral UTF-8 encoding and \n newlines.
>>>> # Above lines and this line are ignored by the patching process.
>>>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td
>>>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Locally Modified (Based On LOCAL)
>>>> @@ -1,3 +1,6 @@
>>>> include0=mahalo.properties
>>>> testClass=PrepareAndCommitExceptionTest
>>>> testCategories=txnmanager,txnmanager_impl
>>>> +#testjvmargs=-Xdebug,\
>>>> +#-Xrunjdwp:transport=dt_socket+,address=8000+,server=y+,suspend=y,\
>>>> +#${testjvmargs}
>>>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java
>>>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Locally Modified (Based On LOCAL)
>>>> @@ -44,15 +44,15 @@
>>>> */
>>>> public class PrepareAndCommitExceptionTest2 extends TxnManagerTest {
>>>>
>>>> -      class Clearer implements Runnable {
>>>> -         TestParticipant part;
>>>> +      static class Clearer implements Runnable {
>>>> +         final TestParticipant part;
>>>>         Clearer(TestParticipant part) {
>>>>             this.part = part;
>>>>         }
>>>>
>>>>         public void run() {
>>>>            try {
>>>> -                Thread.sleep(10000);
>>>> +                Thread.sleep(1000); // was 10 minutes, not necessary on modern hardware.
>>>>            } catch (Exception e) {
>>>>                logger.log(Level.INFO, "Caught sleep exception -- ignoring: " + e);
>>>>            }
>>>> @@ -94,7 +94,7 @@
>>>>        t.start();
>>>>        logger.log(Level.INFO, "Committing transaction");
>>>>        try {
>>>> -            cr.transaction.commit(60000);
>>>> +            cr.transaction.commit(2000); // Was 60 minutes, didn't feel like waiting that long!
>>>>            throw new TestException("ServerException not thrown");
>>>>        } catch (ServerException se) {
>>>>            logger.log(Level.INFO, "Caught expected exception: " + se);
>>>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
>>>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Locally Modified (Based On LOCAL)
>>>> @@ -1,3 +1,4 @@
>>>> include0=mahalo.properties
>>>> testClass=PrepareAndCommitExceptionTest2
>>>> testCategories=txnmanager,txnmanager_impl
>>>> +# This test presently hangs, if the Clearer thread runs after the commit timeout, it doesn't occur.
>>>> \ No newline at end of file
>>>> Index: qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java
>>>> --- qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Locally Modified (Based On LOCAL)
>>>> @@ -68,11 +68,11 @@
>>>>    private long sleep_time = SLEEP_TIME;
>>>>
>>>>    // Another values.
>>>> -    private TransactionManager mgr = null;
>>>> +    private volatile TransactionManager mgr = null;
>>>>    private TaskManager threadpool = null;
>>>> -    private WakeupManager wakeupManager = null;
>>>> -    private Random random;
>>>> -    private long seed = 0;
>>>> +    private volatile WakeupManager wakeupManager = null;
>>>> +    private volatile Random random;
>>>> +    private volatile long seed = 0;
>>>>
>>>>    public Test construct(QAConfig sysConfig) throws Exception {
>>>>        super.construct(sysConfig);
>>>> Index: qa/src/com/sun/jini/test/share/TestParticipantImpl.java
>>>> --- qa/src/com/sun/jini/test/share/TestParticipantImpl.java Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/share/TestParticipantImpl.java Locally Modified (Based On LOCAL)
>>>> @@ -19,6 +19,8 @@
>>>> package com.sun.jini.test.share;
>>>>
>>>> import com.sun.jini.mahalo.*;
>>>> +import java.util.logging.Level;
>>>> +import java.util.logging.Logger;
>>>> import net.jini.core.transaction.*;
>>>> import net.jini.core.transaction.server.*;
>>>>
>>>> @@ -48,15 +50,16 @@
>>>> 	       TransactionParticipant, TestParticipant, ProxyAccessor,
>>>> 	       ServerProxyTrust
>>>> {
>>>> -    private String name;
>>>> -    private BitSet behavior;
>>>> +    private final String name;
>>>> +    private final BitSet behavior;
>>>>    private final Object lock2;
>>>> -    private long crashcount;
>>>> -    private ServerTransaction str;
>>>> +    private volatile long crashcount; // atomic increment with lock2
>>>> +    private volatile ServerTransaction str;
>>>>    private static final long TENSECONDS = 1000 * 10;
>>>>    private static final long THIRTYSECONDS = TENSECONDS *3;
>>>>    private static final boolean DEBUG = true;
>>>> -    private TransactionParticipant proxy;
>>>> +    private volatile TransactionParticipant proxy = null;
>>>> +    private Exporter exporter;
>>>>
>>>>    public TestParticipantImpl() throws RemoteException {
>>>> 	this(DEFAULT_NAME);
>>>> @@ -68,7 +71,7 @@
>>>> 	crashcount = System.currentTimeMillis();
>>>> 	behavior   = new BitSet(OPERATION_COUNT);
>>>> 	Configuration c = QAConfig.getConfig().getConfiguration();
>>>> -	Exporter exporter = QAConfig.getDefaultExporter();
>>>> +	exporter = QAConfig.getDefaultExporter();
>>>> 	if (c instanceof com.sun.jini.qa.harness.QAConfiguration) {
>>>> 	    try {
>>>> 		exporter = (Exporter) c.getEntry("test",
>>>> @@ -78,15 +81,28 @@
>>>> 		throw new RemoteException("Configuration Error", e);
>>>> 	    }
>>>> 	}
>>>> -	proxy = (TransactionParticipant)exporter.export(this);
>>>> +        // Can't export here without this escaping.
>>>>    }
>>>>
>>>>    public Object getProxy() {
>>>> +        if (proxy != null){
>>>> 	return proxy;
>>>> +        } else {
>>>> +            synchronized (lock2){
>>>> +                if (proxy != null) return proxy; // Don't export it twice.
>>>> +                try {
>>>> +                    proxy = (TransactionParticipant)exporter.export(this);
>>>> +                    exporter = null;
>>>> +                } catch (ExportException ex) {
>>>> +                    // Nothing we can do
>>>>    }
>>>> +            }
>>>> +        }
>>>> +        return proxy; // May be null
>>>> +    }
>>>>
>>>>    public TrustVerifier getProxyVerifier() {
>>>> -	return new BasicProxyTrustVerifier(proxy);
>>>> +	return new BasicProxyTrustVerifier(getProxy());
>>>>    }
>>>>
>>>>    private boolean checkBit(int bit) {
>>>> @@ -136,7 +152,7 @@
>>>> 		System.out.println(name + ": joining");
>>>> 	    }
>>>>
>>>> -	    str.join(proxy, crashcount);
>>>> +	    str.join((TransactionParticipant) getProxy(), crashcount);
>>>> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
>>>> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
>>>> 		    doTimeout(THIRTYSECONDS);
>>>> @@ -157,7 +173,7 @@
>>>> 		System.out.println(name + ": joining again");
>>>> 	    }
>>>>
>>>> -	    str.join(proxy, crashcount);
>>>> +	    str.join((TransactionParticipant) getProxy(), crashcount);
>>>>
>>>> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
>>>> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
>>>> Index: qa/src/com/sun/jini/test/share/TxnManagerTest.java
>>>> --- qa/src/com/sun/jini/test/share/TxnManagerTest.java Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/share/TxnManagerTest.java Locally Modified (Based On LOCAL)
>>>> @@ -42,16 +42,20 @@
>>>> {
>>>>    protected static final boolean DEBUG = true;
>>>>
>>>> -    TransactionManager[] mgrs = new TransactionManager[1];
>>>> +    final TransactionManager[] mgrs = new TransactionManager[1];
>>>>
>>>>    public TransactionManager manager() throws RemoteException {
>>>> +        synchronized (mgrs){
>>>> 	return (TransactionManager) mgrs[0];
>>>>    }
>>>> +    }
>>>>
>>>>    protected void startTxnMgr() throws TestException {
>>>> 	specifyServices(new Class[] {TransactionManager.class});
>>>> +        synchronized (mgrs){
>>>> 	mgrs[0]= (TransactionManager)services[0]; // prepared by specifyServices
>>>>    }
>>>> +    }
>>>>
>>>>    public Test construct(QAConfig config) throws Exception {
>>>>        super.construct(config);
>>>> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java
>>>> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Locally Modified (Based On LOCAL)
>>>> @@ -192,7 +192,9 @@
>>>>            if (trc == null) {
>>>>                throw new TestException("Null transaction has been obtained.");
>>>>            }
>>>> +            synchronized (txns){
>>>>            txns.add(trc.transaction);
>>>> +            }
>>>>            return trc.transaction;
>>>>        } catch (Exception e) {
>>>>            throw new TestException("Could not create transaction.", e);
>>>> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties
>>>> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Locally Modified (Based On LOCAL)
>>>> @@ -15,8 +15,8 @@
>>>>
>>>> # timeout2 must be greater than (timeout1 + instantTime)
>>>> # it is recommended that timeout2 be greater than (timeout1 + 2*instantTime)
>>>> -com.sun.jini.test.spec.javaspace.conformance.timeout1=24000
>>>> -com.sun.jini.test.spec.javaspace.conformance.timeout2=48000
>>>> +com.sun.jini.test.spec.javaspace.conformance.timeout1=20000
>>>> +com.sun.jini.test.spec.javaspace.conformance.timeout2=40000
>>>>
>>>> #  general round trip time expected to non-blocking operations.
>>>> #  should be set to checkTime / 2.
>>>> Index: qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java
>>>> --- qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Locally Modified (Based On LOCAL)
>>>> @@ -80,11 +80,11 @@
>>>>            while (true) {
>>>>                state = str.mgr.getState(str.id);
>>>>
>>>> -                if (DEBUG) {
>>>> -                    int st = state;
>>>> -                    logger.log(Level.INFO, "state = "
>>>> -                            + com.sun.jini.constants.TxnConstants.getName(st));
>>>> -                }
>>>> +//                if (DEBUG) {
>>>> +//                    int st = state;
>>>> +//                    logger.log(Level.FINEST, "state = "
>>>> +//                            + com.sun.jini.constants.TxnConstants.getName(st));
>>>> +//                }
>>>>
>>>>                if (state == COMMITTED) {
>>>>                    break;
>>>> Index: qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java
>>>> --- qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Base (BASE)
>>>> +++ qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Locally Modified (Based On LOCAL)
>>>> @@ -21,15 +21,16 @@
>>>>
>>>>
>>>> class CommitThread extends Thread {
>>>> -    long timeOut;
>>>> -    Transaction tr;
>>>> +    final long timeOut;
>>>> +    final Transaction tr;
>>>>
>>>>    public CommitThread(Transaction tr) {
>>>>        this.tr = tr;
>>>> +        timeOut = 0;
>>>>    }
>>>>
>>>>    public CommitThread(Transaction tr, long timeOut) {
>>>> -        this(tr);
>>>> +        this.tr = tr;
>>>>
>>>>        if (timeOut<  0) {
>>>>            throw new IllegalArgumentException("timeout must be non-negative");
>>>> Index: src/com/sun/jini/collection/WeakTable.java
>>>> --- src/com/sun/jini/collection/WeakTable.java Base (BASE)
>>>> +++ src/com/sun/jini/collection/WeakTable.java Locally Modified (Based On LOCAL)
>>>> @@ -52,16 +52,16 @@
>>>> */
>>>> public class WeakTable {
>>>>    /** The map of known objects.  */
>>>> -    private HashMap		table = new HashMap();
>>>> +    private final HashMap table;
>>>>
>>>>    /** The queue of cleared SpaceProxy objects. */
>>>> -    private ReferenceQueue	refQueue = new ReferenceQueue();
>>>> +    private final ReferenceQueue refQueue;
>>>>
>>>>    /** Print debug messages to this stream if not<code>null</code>. */
>>>>    private static PrintStream		DEBUG = null;
>>>>
>>>>    /** Object to call back when keys are collected */
>>>> -    private KeyGCHandler handler = null;
>>>> +    private final KeyGCHandler handler;
>>>>
>>>>    /**
>>>>     * Create a new WeakTable object to maintain the maps.
>>>> @@ -72,6 +72,7 @@
>>>>
>>>> 	table = new HashMap();
>>>> 	refQueue = new ReferenceQueue();
>>>> +        handler = null;
>>>>    }
>>>>
>>>>    /**
>>>> @@ -79,7 +80,11 @@
>>>>     * back the designated object when keys are collected.
>>>>     */
>>>>    public WeakTable(KeyGCHandler handler) {
>>>> -	this();
>>>> +        if (DEBUG != null)
>>>> +	    DEBUG.println("Creating WeakTable");
>>>> +
>>>> +	table = new HashMap();
>>>> +	refQueue = new ReferenceQueue();
>>>> 	this.handler = handler;
>>>>    }
>>>>
>>>> Index: src/com/sun/jini/mahalo/AbortJob.java
>>>> --- src/com/sun/jini/mahalo/AbortJob.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/AbortJob.java Locally Modified (Based On LOCAL)
>>>> @@ -29,6 +29,7 @@
>>>> import java.rmi.ConnectIOException;
>>>> import java.rmi.AccessException;
>>>> import java.rmi.ConnectException;
>>>> +import java.util.Iterator;
>>>>
>>>> import java.util.logging.Level;
>>>> import java.util.logging.Logger;
>>>> @@ -54,10 +55,10 @@
>>>> *
>>>> */
>>>> public class AbortJob extends Job implements TransactionConstants {
>>>> -    ServerTransaction tr;
>>>> -    ClientLog log;
>>>> -    ParticipantHandle[] handles;
>>>> -    int maxtries = 5;
>>>> +    final ServerTransaction tr;
>>>> +    final ClientLog log;
>>>> +    final ParticipantHandle[] handles;
>>>> +    final int maxtries = 5;
>>>>    static final Logger logger = TxnManagerImpl.participantLogger;
>>>>
>>>>    /**
>>>> @@ -272,13 +273,16 @@
>>>> 	int tmp = 0;
>>>> 	int count = 0;
>>>>
>>>> -	checkresults:
>>>> -	for (int i = 0; i<  results.length; i++) {
>>>> -	    tmp = ((Integer)results[i]).intValue();
>>>> -
>>>> -	    if (tmp == ABORTED)
>>>> -		count++;
>>>> +        synchronized (this){
>>>> +            Iterator i = results.values().iterator();
>>>> +            while (i.hasNext()){
>>>> +                Object res = i.hasNext();
>>>> +                if (res instanceof Integer){
>>>> +                    tmp = ((Integer)res).intValue();
>>>> +                    if (tmp == ABORTED) count++;
>>>> 	}
>>>> +            }
>>>> +        }
>>>>
>>>>        if (logger.isLoggable(Level.FINEST)) {
>>>>            logger.log(Level.FINEST,
>>>> Index: src/com/sun/jini/mahalo/AbortRecord.java
>>>> --- src/com/sun/jini/mahalo/AbortRecord.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/AbortRecord.java Locally Modified (Based On LOCAL)
>>>> @@ -33,7 +33,7 @@
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private ParticipantHandle[] parts;
>>>> +    private final ParticipantHandle[] parts;
>>>>
>>>>    static final long serialVersionUID = -8121722031382234695L;
>>>>
>>>> Index: src/com/sun/jini/mahalo/CommitJob.java
>>>> --- src/com/sun/jini/mahalo/CommitJob.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/CommitJob.java Locally Modified (Based On LOCAL)
>>>> @@ -29,6 +29,7 @@
>>>> import java.rmi.ConnectIOException;
>>>> import java.rmi.AccessException;
>>>> import java.rmi.ConnectException;
>>>> +import java.util.Iterator;
>>>>
>>>> import java.util.logging.Level;
>>>> import java.util.logging.Logger;
>>>> @@ -51,10 +52,10 @@
>>>> * @see net.jini.core.transaction.server.TransactionParticipant
>>>> */
>>>> public class CommitJob extends Job implements TransactionConstants {
>>>> -    ServerTransaction tr;
>>>> -    ClientLog log;
>>>> -    ParticipantHandle[] handles;
>>>> -    int maxtries = Integer.MAX_VALUE;
>>>> +    final ServerTransaction tr;
>>>> +    final ClientLog log;
>>>> +    final ParticipantHandle[] handles;
>>>> +    final int maxtries = Integer.MAX_VALUE;
>>>>    static final Logger logger = TxnManagerImpl.participantLogger;
>>>>
>>>>    /**
>>>> @@ -266,13 +267,13 @@
>>>> 	int tmp = 0;
>>>> 	int count = 0;
>>>>
>>>> -	checkresults:
>>>> -	for (int i = 0; i<  results.length; i++) {
>>>> -	    tmp = ((Integer)results[i]).intValue();
>>>> -
>>>> -	    if (tmp == COMMITTED)
>>>> -		count++;
>>>> +        synchronized (this){
>>>> +            Iterator i = results.values().iterator();
>>>> +            while (i.hasNext()){
>>>> +                tmp = ((Integer)i.next()).intValue();
>>>> +                if (tmp == COMMITTED) count++;
>>>> 	}
>>>> +        }
>>>>
>>>>        if (logger.isLoggable(Level.FINEST)) {
>>>>            logger.log(Level.FINEST,
>>>> Index: src/com/sun/jini/mahalo/CommitRecord.java
>>>> --- src/com/sun/jini/mahalo/CommitRecord.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/CommitRecord.java Locally Modified (Based On LOCAL)
>>>> @@ -39,7 +39,7 @@
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
>>>> +    final ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
>>>> 			       //      We want a list of things.  By using
>>>> 			       //      an array, we can use the type system
>>>> 			       //      to guarantee that each thing is a
>>>> Index: src/com/sun/jini/mahalo/Job.java
>>>> --- src/com/sun/jini/mahalo/Job.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/Job.java Locally Modified (Based On LOCAL)
>>>> @@ -19,9 +19,13 @@
>>>>
>>>> import com.sun.jini.thread.TaskManager;
>>>> import com.sun.jini.thread.WakeupManager;
>>>> +import java.util.ArrayList;
>>>> import java.util.HashMap;
>>>> +import java.util.List;
>>>> import java.util.Map;
>>>> import java.util.Set;
>>>> +import java.util.concurrent.ConcurrentHashMap;
>>>> +import java.util.concurrent.atomic.AtomicIntegerArray;
>>>> import java.util.logging.Level;
>>>> import java.util.logging.Logger;
>>>>
>>>> @@ -34,14 +38,15 @@
>>>> *
>>>> */
>>>> public abstract class Job {
>>>> -    private TaskManager pool;
>>>> -    private WakeupManager wm;
>>>> -    private int pending = -1;
>>>> -    Object[] results;
>>>> -    int[] attempts;
>>>> -    private Map tasks = new HashMap();  //used to maintain account
>>>> +    private final TaskManager pool;
>>>> +    private final WakeupManager wm;
>>>> +    private int pending = -1; // Synchronized on this.
>>>> +    final Map<Integer,Object>  results = new HashMap<Integer,Object>(); // sync on this.
>>>> +    volatile AtomicIntegerArray attempts; // reference changed while synchronized on this
>>>> +    private final Map<Object,Integer>  tasks = new HashMap<Object,Integer>();  //used to maintain account
>>>> 					//of the tasks for which
>>>> 					//the job is responsible
>>>> +                                        // sync on tasks.
>>>>
>>>>    static final Logger logger = TxnManagerImpl.participantLogger;
>>>>
>>>> @@ -75,23 +80,31 @@
>>>> 	}
>>>>
>>>> 	if (tmp == null)
>>>> -	    throw new UnknownTaskException();
>>>> +	    throw new UnknownTaskException("Task didn't belong to this job");
>>>>
>>>> 	int rank = tmp.intValue();
>>>>
>>>> -	synchronized (attempts) {
>>>> -	    attempts[rank]++;
>>>> -	}
>>>> +//	synchronized (attempts) {
>>>> +//	    attempts[rank]++;
>>>> +//	}
>>>>
>>>> -	Object result = doWork(who, param);
>>>> -	if (result == null)
>>>> +        attempts.incrementAndGet(rank);
>>>> +
>>>> +	Object r = doWork(who, param);
>>>> +	if (r == null)
>>>> 	    return false;
>>>>
>>>> 	try {
>>>> -	    reportDone(who, result);
>>>> +	    reportDone(who, r);
>>>> 	} catch (UnknownTaskException e) {
>>>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>>>> +            e.printStackTrace(System.err);
>>>> 	} catch (PartialResultException e) {
>>>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>>>> +            e.printStackTrace(System.err);
>>>> 	} catch (JobException e) {
>>>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>>>> +            e.printStackTrace(System.err);
>>>> 	}
>>>>
>>>> 	return true;
>>>> @@ -112,15 +125,14 @@
>>>> 	    tmp = (Integer)tasks.get(who);
>>>> 	}
>>>>
>>>> -	if (tmp == null)
>>>> -	    throw new UnknownTaskException();
>>>> +	if (tmp == null) throw new UnknownTaskException();
>>>>
>>>> 	int rank = tmp.intValue();
>>>> -
>>>> -	synchronized(attempts)  {
>>>> -	    return attempts[rank];
>>>> +//	synchronized(attempts)  {
>>>> +//	    return attempts[rank];
>>>> +//	}
>>>> +        return attempts.get(rank);
>>>> 	}
>>>> -    }
>>>>
>>>>
>>>>
>>>> @@ -150,37 +162,39 @@
>>>>     */
>>>>    public void scheduleTasks() {
>>>> 	TaskManager.Task[] tmp = createTasks();
>>>> -
>>>> +        int length = tmp.length;
>>>> 	if (tmp != null) {
>>>>            if (logger.isLoggable(Level.FINEST)) {
>>>>                logger.log(Level.FINEST,
>>>>                    "Job:scheduleTasks with {0} tasks",
>>>> -                    Integer.valueOf(tmp.length));
>>>> +                    Integer.valueOf(length));
>>>>            }
>>>>
>>>> -	    results = new Object[tmp.length];
>>>> -	    attempts = new int[tmp.length];
>>>> -	    setPending(tmp.length);
>>>> +            synchronized (this){
>>>> +                results.clear();
>>>> +                attempts = new AtomicIntegerArray(length);
>>>> +                setPending(length);
>>>> +            }
>>>> +            for (int i = 0; i<  length; i++) {
>>>>
>>>> -	    for (int i = 0; i<  tmp.length; i++) {
>>>> -
>>>> 		//Record the position if each
>>>> 		//task for later use when assembling
>>>> 		//the partial results
>>>>
>>>> 		synchronized(tasks) {
>>>> 		    tasks.put(tmp[i],Integer.valueOf(i));
>>>> +                }
>>>> 		    pool.add(tmp[i]);
>>>>                    if (logger.isLoggable(Level.FINEST)) {
>>>>                        logger.log(Level.FINEST,
>>>>                            "Job:scheduleTasks added {0} to thread pool",
>>>>                            tmp[i]);
>>>>                    }
>>>> -		    attempts[i] = 0;
>>>> +                attempts.set(i,0);
>>>> 		}
>>>> +
>>>> 	    }
>>>> 	}
>>>> -    }
>>>>
>>>>
>>>>    private synchronized void awaitPending(long waitFor) {
>>>> @@ -289,19 +303,21 @@
>>>> 	if (position == null)
>>>> 	    throw new UnknownTaskException();
>>>>
>>>> -	synchronized(results) {
>>>> -	    if (results[position.intValue()] == null) {
>>>> +        synchronized (this){
>>>> +            Object exists = results.get(position);
>>>> +            if (exists == null){
>>>>                if (logger.isLoggable(Level.FINEST)) {
>>>>                    logger.log(Level.FINEST,
>>>>                        "Job:reportDone who = {0}, param = {1}",
>>>> 		        new Object[] { who, param});
>>>>                }
>>>> -	        results[position.intValue()] = param;
>>>> +                results.put(position, param);
>>>> 	        decrementPending();
>>>> 	    } else {
>>>> 	        throw new PartialResultException("result already set");
>>>> 	    }
>>>> 	}
>>>> +
>>>>    }
>>>>
>>>>
>>>> @@ -347,21 +363,25 @@
>>>>     * the<code>Job</code>
>>>>     */
>>>>    public void stop() {
>>>> +        Object[] vals;
>>>> +        synchronized (tasks){
>>>> 	Set s = tasks.keySet();
>>>> -	Object[] vals = s.toArray();
>>>> +            vals = s.toArray();
>>>> +            tasks.clear();
>>>> +        }
>>>>
>>>> 	//Remove and interrupt all tasks
>>>> -
>>>> -	for (int i = 0; i<  vals.length; i++) {
>>>> +        int l = vals.length;
>>>> +	for (int i = 0; i<  l; i++) {
>>>> 	    TaskManager.Task t = (TaskManager.Task) vals[i];
>>>> 	    pool.remove(t);
>>>> 	}
>>>>
>>>> 	//Erase record of tasks, results and the
>>>> 	//counting mechanism
>>>> -
>>>> -	tasks = new HashMap();
>>>> +        synchronized (this){
>>>> 	setPending(-1);
>>>> -	results = null;
>>>> +            results.clear();
>>>>    }
>>>> }
>>>> +}
>>>> Index: src/com/sun/jini/mahalo/JoinStateManager.java
>>>> --- src/com/sun/jini/mahalo/JoinStateManager.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/JoinStateManager.java Locally Modified (Based On LOCAL)
>>>> @@ -74,41 +74,41 @@
>>>>    private static final Logger persistenceLogger = TxnManagerImpl.persistenceLogger;
>>>>
>>>>    /**<code>ProxyPreparer</code>  for<code>LookupLocators</code>  */
>>>> -    private ProxyPreparer lookupLocatorPreparer;
>>>> +    private volatile ProxyPreparer lookupLocatorPreparer;
>>>>
>>>>    /**
>>>>     * Object used to find lookups. Has to implement DiscoveryManagement
>>>>     * and DiscoveryLocatorManagement as well as DiscoveryGroupManagement.
>>>>     */
>>>> -    private DiscoveryManagement dm;
>>>> +    private volatile DiscoveryManagement dm;
>>>>
>>>>    /**
>>>>     *<code>JoinManager</code>  that is handling the details of binding
>>>>     * into Jini lookup services.
>>>>     */
>>>> -    private JoinManager  mgr;
>>>> +    private volatile JoinManager  mgr;
>>>>
>>>>    /**
>>>>     * The object coordinating our persistent state.
>>>>     */
>>>> -    private ReliableLog log;
>>>> +    private volatile ReliableLog log;
>>>>
>>>>    /**
>>>>     * The join state, this data needs to be persisted between restarts
>>>>     */
>>>> -    private Entry[]		attributes;
>>>> -    private LookupLocator[]	locators;
>>>> -    private String[]		groups;
>>>> +    private volatile Entry[]		attributes;
>>>> +    private volatile LookupLocator[]	locators;
>>>> +    private volatile String[]		groups;
>>>>
>>>>    /** Service's internal<code>Uuid</code>  which needs to be persisted */
>>>> -    private Uuid		serviceUuid;
>>>> +    private volatile Uuid		serviceUuid;
>>>>
>>>>    /**
>>>>     * Conceptually, true if this is the first time this
>>>>     * service has come up, implemented as if there was
>>>>     * no previous state then this is the first time.
>>>>     */
>>>> -    private boolean initial = true;
>>>> +    private volatile boolean initial = true;
>>>>
>>>>    /**
>>>>     * Simple constructor.
>>>> Index: src/com/sun/jini/mahalo/LeaseExpirationMgr.java
>>>> --- src/com/sun/jini/mahalo/LeaseExpirationMgr.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/LeaseExpirationMgr.java Locally Modified (Based On LOCAL)
>>>> @@ -57,9 +57,9 @@
>>>>
>>>>
>>>>    // Map of resources to tickets
>>>> -    private WeakTable		ticketMap = new WeakTable(this);
>>>> -    private Expirer		landlord;
>>>> -    private WakeupManager expirationQueue
>>>> +    private final WeakTable		ticketMap = new WeakTable(this);
>>>> +    private final Expirer		landlord;
>>>> +    private final WakeupManager expirationQueue
>>>>        = new WakeupManager(new WakeupManager.ThreadDesc(null, true));
>>>>
>>>>    /**
>>>> Index: src/com/sun/jini/mahalo/ParticipantHandle.java
>>>> --- src/com/sun/jini/mahalo/ParticipantHandle.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/ParticipantHandle.java Locally Modified (Based On LOCAL)
>>>> @@ -38,17 +38,17 @@
>>>>    /**
>>>>     * Cached reference to prepared participant.
>>>>     */
>>>> -    private transient TransactionParticipant preparedPart;
>>>> +    private volatile transient TransactionParticipant preparedPart;
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private StorableObject storedpart;
>>>> +    private final StorableObject storedpart;
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private long crashcount = 0;
>>>> +    private volatile long crashcount = 0;
>>>>
>>>>    /**
>>>>     * @serial
>>>> @@ -70,6 +70,7 @@
>>>>        if (preparedPart == null)
>>>> 	    throw new NullPointerException(
>>>> 	        "TransactionParticipant argument cannot be null");
>>>> +        StorableObject storedpart = null;
>>>> 	try {
>>>> 	    storedpart = new StorableObject(preparedPart);
>>>> 	    this.preparedPart = preparedPart;
>>>> @@ -80,6 +81,7 @@
>>>> 		    "Cannot store the TransactionParticipant", re);
>>>> 	    }
>>>> 	}
>>>> +        this.storedpart = storedpart;
>>>> 	this.prepstate = ACTIVE;
>>>>    }
>>>>
>>>> Index: src/com/sun/jini/mahalo/ParticipantModRecord.java
>>>> --- src/com/sun/jini/mahalo/ParticipantModRecord.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/ParticipantModRecord.java Locally Modified (Based On LOCAL)
>>>> @@ -38,12 +38,12 @@
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private ParticipantHandle part;
>>>> +    private final ParticipantHandle part;
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private int result;
>>>> +    private final int result;
>>>>
>>>>    ParticipantModRecord(ParticipantHandle part, int result) {
>>>> 	if (part == null)
>>>> Index: src/com/sun/jini/mahalo/ParticipantTask.java
>>>> --- src/com/sun/jini/mahalo/ParticipantTask.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/ParticipantTask.java Locally Modified (Based On LOCAL)
>>>> @@ -17,6 +17,7 @@
>>>> */
>>>> package com.sun.jini.mahalo;
>>>>
>>>> +import com.sun.jini.logging.Levels;
>>>> import com.sun.jini.thread.RetryTask;
>>>> import com.sun.jini.thread.TaskManager;
>>>> import com.sun.jini.thread.WakeupManager;
>>>> @@ -35,8 +36,8 @@
>>>> * @see TaskManager
>>>> */
>>>> public class ParticipantTask extends RetryTask {
>>>> -    ParticipantHandle handle;
>>>> -    Job myjob;
>>>> +    final ParticipantHandle handle;
>>>> +    final Job myjob;
>>>>    private static final Logger operationsLogger =
>>>>        TxnManagerImpl.operationsLogger;
>>>> 	
>>>> @@ -81,9 +82,11 @@
>>>> 	} catch (UnknownTaskException ute) {
>>>> 	    //If task doesn't belong to the
>>>> 	    //Job, then stop doing work.
>>>> +            logger.log(Level.FINE, "Task didn't belong to job",ute);
>>>> +            ute.printStackTrace(System.err);
>>>> 	    result = true;
>>>> 	} catch (JobException je) {
>>>> -	    je.printStackTrace();
>>>> +	    je.printStackTrace(System.err);
>>>> 	}
>>>>        if (operationsLogger.isLoggable(Level.FINER)) {
>>>>            operationsLogger.exiting(ParticipantTask.class.getName(),
>>>> Index: src/com/sun/jini/mahalo/PrepareAndCommitJob.java
>>>> --- src/com/sun/jini/mahalo/PrepareAndCommitJob.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/PrepareAndCommitJob.java Locally Modified (Based On LOCAL)
>>>> @@ -45,10 +45,10 @@
>>>> * @see net.jini.core.transaction.server.TransactionParticipant
>>>> */
>>>> public class PrepareAndCommitJob extends Job implements TransactionConstants {
>>>> -    ServerTransaction tr;
>>>> -    ClientLog log;
>>>> -    ParticipantHandle handle;
>>>> -    int maxtries = 5;
>>>> +    final ServerTransaction tr;
>>>> +    final ClientLog log;
>>>> +    final ParticipantHandle handle;
>>>> +    final int maxtries = 5;
>>>>
>>>>    /*
>>>>     * Field that holds the last received remote exception, if any.
>>>> @@ -290,7 +290,9 @@
>>>>
>>>> 	int prepstate = NOTCHANGED;
>>>>
>>>> -	prepstate = ((Integer)results[0]).intValue();
>>>> +        synchronized (this){
>>>> +            prepstate = ((Integer) results.get(Integer.valueOf(0))).intValue();
>>>> +        }
>>>>
>>>>        Integer result = Integer.valueOf(prepstate);
>>>>        if (operationsLogger.isLoggable(Level.FINER)) {
>>>> Index: src/com/sun/jini/mahalo/PrepareJob.java
>>>> --- src/com/sun/jini/mahalo/PrepareJob.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/PrepareJob.java Locally Modified (Based On LOCAL)
>>>> @@ -22,6 +22,7 @@
>>>> import com.sun.jini.thread.TaskManager;
>>>> import com.sun.jini.thread.WakeupManager;
>>>> import java.rmi.RemoteException;
>>>> +import java.util.Iterator;
>>>> import java.util.logging.Level;
>>>> import java.util.logging.Logger;
>>>> import net.jini.core.transaction.Transaction;
>>>> @@ -273,10 +274,11 @@
>>>> 	int prepstate = NOTCHANGED;
>>>> 	int tmp = 0;
>>>>
>>>> -	checkresults:
>>>> -	for (int i = 0; i<  results.length; i++) {
>>>> -	    tmp = ((Integer)results[i]).intValue();
>>>> -
>>>> +        synchronized (this){
>>>> +            Iterator i = results.values().iterator();
>>>> +            checkresult:
>>>> +            while (i.hasNext()){
>>>> +                tmp = ((Integer) i.next()).intValue();
>>>> 	    switch(tmp) {
>>>> 	      case NOTCHANGED:
>>>> 		//Does not affect the prepstate
>>>> @@ -288,7 +290,7 @@
>>>> 		//aborts the whole transaction.
>>>>
>>>> 		prepstate = ABORTED;
>>>> -		break checkresults;
>>>> +                    break checkresult;
>>>>
>>>> 	      case PREPARED:
>>>> 		//changes the state to PREPARED only
>>>> @@ -298,11 +300,13 @@
>>>> 		break;
>>>> 	    }
>>>> 	}
>>>> -	Integer result = Integer.valueOf(prepstate);
>>>> +        }
>>>> +
>>>> +	Integer r = Integer.valueOf(prepstate);
>>>>        if (operationsLogger.isLoggable(Level.FINER)) {
>>>>            operationsLogger.exiting(PrepareJob.class.getName(),
>>>> -                "computeResult", result);
>>>> +                "computeResult", r);
>>>> 	}
>>>> -	return result;
>>>> +	return r;
>>>>    }
>>>> }
>>>> Index: src/com/sun/jini/mahalo/SettlerTask.java
>>>> --- src/com/sun/jini/mahalo/SettlerTask.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/SettlerTask.java Locally Modified (Based On LOCAL)
>>>> @@ -39,10 +39,10 @@
>>>> */
>>>>
>>>> public class SettlerTask extends RetryTask implements TransactionConstants {
>>>> -    private long tid;
>>>> -    private int attempt;
>>>> -    private int maxtries = Integer.MAX_VALUE;
>>>> -    private TransactionManager txnmgr;
>>>> +    private final long tid;
>>>> +    private int attempt; // sync on this.
>>>> +    private final int maxtries = Integer.MAX_VALUE;
>>>> +    private final TransactionManager txnmgr;
>>>>
>>>>    /** Logger for operations related messages */
>>>>    private static final Logger operationsLogger =
>>>> @@ -89,10 +89,12 @@
>>>> 	        "tryOnce");
>>>> 	}
>>>>        try {
>>>> +            synchronized (this){
>>>> 	    if (attempt>= maxtries)
>>>> 		return true;
>>>>
>>>> 	    attempt++;
>>>> +            }
>>>>
>>>> 	    if (transactionsLogger.isLoggable(Level.FINEST)) {
>>>>                transactionsLogger.log(Level.FINEST,
>>>> Index: src/com/sun/jini/mahalo/StorableObject.java
>>>> --- src/com/sun/jini/mahalo/StorableObject.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/StorableObject.java Locally Modified (Based On LOCAL)
>>>> @@ -19,6 +19,7 @@
>>>> package com.sun.jini.mahalo;
>>>>
>>>> import java.io.IOException;
>>>> +import java.io.ObjectInputStream;
>>>> import java.rmi.MarshalledObject;
>>>> import java.rmi.RemoteException;
>>>>
>>>> @@ -39,8 +40,8 @@
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private MarshalledObject	bytes;	// the serialized bytes
>>>> -    private transient Object	obj;	// the cached object reference
>>>> +    private final MarshalledObject	bytes;	// the serialized bytes
>>>> +    private volatile transient Object	obj;	// the cached object reference
>>>>
>>>>    private static final boolean DEBUG = false;
>>>>    private static final long serialVersionUID = -3793675220968988873L;
>>>> @@ -50,16 +51,25 @@
>>>>     * in a<code>MarshalledObject</code>.
>>>>     */
>>>>    public StorableObject(Object obj) throws RemoteException {
>>>> +	this(obj, toMO(obj));
>>>> +    }
>>>> +
>>>> +    private static MarshalledObject toMO(Object obj) throws RemoteException{
>>>> 	try {
>>>> -	    bytes = new MarshalledObject(obj);
>>>> -	    this.obj = obj;
>>>> -	} catch (RemoteException e) {
>>>> +            return new MarshalledObject(obj);
>>>> +        } catch (RemoteException e){
>>>> 	    throw e;
>>>> -	} catch (IOException e) {
>>>> +        } catch (IOException e){
>>>> 	    fatalError("can't encode object", e);
>>>> 	}
>>>> +        return null; //Unreachable.
>>>>    }
>>>>
>>>> +    private StorableObject (Object obj, MarshalledObject mo){
>>>> +        bytes = mo;
>>>> +        this.obj = obj;
>>>> +    }
>>>> +
>>>>    /**
>>>>     * Return the<code>hashCode</code>  of the<code>MarshalledObject</code>.
>>>>     */
>>>> @@ -103,6 +113,12 @@
>>>> 	return null;	// not reached, but compiler doesn't know
>>>>    }
>>>>
>>>> +    private void readObject(ObjectInputStream s)
>>>> +                                   throws IOException, ClassNotFoundException
>>>> +        {
>>>> +            s.defaultReadObject(); // Just in case we change serial form later.
>>>> +        }
>>>> +
>>>>    /**
>>>>     * Unrecoverable error happened -- show it and give up the ghost.
>>>>     */
>>>> Index: src/com/sun/jini/mahalo/TxnManagerImpl.java
>>>> --- src/com/sun/jini/mahalo/TxnManagerImpl.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/TxnManagerImpl.java Locally Modified (Based On LOCAL)
>>>> @@ -62,6 +62,7 @@
>>>> import java.util.Iterator;
>>>> import java.util.Map;
>>>> import java.util.Vector;
>>>> +import java.util.concurrent.ConcurrentMap;
>>>> import java.util.logging.Level;
>>>> import java.util.logging.Logger;
>>>>
>>>> @@ -149,28 +150,6 @@
>>>>    static final Logger persistenceLogger =
>>>>        Logger.getLogger(TxnManager.MAHALO + ".persistence");
>>>>
>>>> -    /* At some point earlier in the development, it appears this object
>>>> -     * was Serializable, or was declared so, such that it replaced itself
>>>> -     * with a proxy stub.  This is a test to ensure serialization doesn't
>>>> -     * occur.
>>>> -     */
>>>> -
>>>> -    private void writeObject(java.io.ObjectOutputStream out)
>>>> -     throws IOException {
>>>> -        throw new IOException("Serialization not supported");
>>>> -    }
>>>> -    private void readObject(java.io.ObjectInputStream in)
>>>> -     throws IOException, ClassNotFoundException {
>>>> -        throw new IOException("Serialization not supported");
>>>> -    }
>>>> -    private void readObjectNoData()
>>>> -     throws ObjectStreamException{
>>>> -        throw new ObjectStreamException("Serialization not supported"){
>>>> -            private static final long serialVersionUID = 1L;
>>>> -        };
>>>> -    }
>>>> -
>>>> -
>>>>    private volatile LogManager logmgr;
>>>>    /* Retrieve values from properties.          */
>>>>    /* Its important here to schedule SettlerTasks on a */
>>>> @@ -186,7 +165,7 @@
>>>>    private final WakeupManager taskWakeupMgr;
>>>>    /* Map of transaction ids are their associated, internal
>>>>     * transaction representations */
>>>> -    private final Map<Long,TxnManagerTransaction>  txns;
>>>> +    private final ConcurrentMap<Long,TxnManagerTransaction>  txns;
>>>>    private final Vector<Long>  unsettledtxns = new Vector<Long>();
>>>>    private final InterruptedStatusThread settleThread;
>>>>    private final String persistenceDirectory;
>>>> @@ -390,7 +369,7 @@
>>>>                settleThread = init.settleThread;
>>>>            } else {
>>>>                // Assign init fields
>>>> -                txns = Collections.emptyMap();
>>>> +                txns = null;
>>>>                /* Retrieve values from properties.          */
>>>>                activationSystem = null;
>>>>                activationID = activID;
>>>> @@ -627,8 +606,7 @@
>>>> 	        "prepared participant: {0}", preparedTarget);
>>>> 	}
>>>>
>>>> -        TxnManagerTransaction txntr =
>>>> -		(TxnManagerTransaction) txns.get(Long.valueOf(id));
>>>> +        TxnManagerTransaction txntr = txns.get(Long.valueOf(id));
>>>>
>>>> 	if (txntr == null)
>>>> 	    throw new UnknownTransactionException("unknown transaction");
>>>> @@ -645,6 +623,7 @@
>>>>    public int getState(long id)
>>>>        throws UnknownTransactionException
>>>>    {
>>>> +
>>>>        if (operationsLogger.isLoggable(Level.FINER)) {
>>>>            operationsLogger.entering(
>>>> 		TxnManagerImpl.class.getName(), "getState",
>>>> @@ -652,9 +631,8 @@
>>>> 	}
>>>>        readyState.check();
>>>>
>>>> -        TxnManagerTransaction txntr =
>>>> -	        (TxnManagerTransaction) txns.get(Long.valueOf(id));
>>>> -
>>>> +        TxnManagerTransaction txntr = null;
>>>> +                txntr = txns.get(Long.valueOf(id));
>>>> 	if (txntr == null)
>>>> 	    throw new UnknownTransactionException("unknown transaction");
>>>>        /* Expiration checks are only meaningful for active transactions. */
>>>> @@ -669,17 +647,18 @@
>>>> 	 * a false result.
>>>> 	 */
>>>> //TODO - need better locking here. getState and expiration need to be checked atomically	
>>>> -        int state = txntr.getState();
>>>> -        if (state == ACTIVE&&  !ensureCurrent(txntr))
>>>> -	    throw new UnknownTransactionException("unknown transaction");
>>>> -	
>>>> +        try{
>>>> +            int state = txntr.atomicCheckExpirationIfActive();
>>>> 	if (operationsLogger.isLoggable(Level.FINER)) {
>>>>            operationsLogger.exiting(
>>>> 		TxnManagerImpl.class.getName(), "getState",
>>>> 	        Integer.valueOf(state));
>>>> 	}
>>>> 	return state;
>>>> +        } catch (TransactionException ex) {
>>>> +            throw new UnknownTransactionException("unknown transaction");
>>>>    }
>>>> +    }
>>>>
>>>>
>>>>    public void commit(long id)
>>>> @@ -901,12 +880,14 @@
>>>>                    transactionsLogger.log(Level.FINEST,
>>>>                        "Settler waiting");
>>>> 	        }
>>>> -		wait();
>>>> -
>>>> -	        if (transactionsLogger.isLoggable(Level.FINEST)) {
>>>> -                    transactionsLogger.log(Level.FINEST,
>>>> -                        "Settler notified");
>>>> -	        }
>>>> +                // Don't wait forever, in case we're not notified, break out
>>>> +                // early and check condition.
>>>> +		wait(10000L);
>>>> +                // Due to spurious wakeup and break out after ten seconds, the following log message is inaccurate.
>>>> +//	        if (transactionsLogger.isLoggable(Level.FINEST)) {
>>>> +//                    transactionsLogger.log(Level.FINEST,
>>>> +//                        "Settler notified");
>>>> +//	        }
>>>> 		continue;
>>>> 	    }
>>>>
>>>> @@ -1018,6 +999,7 @@
>>>>
>>>> 	// synchronize on the resource so there is not a race condition
>>>> 	// between renew and expiration
>>>> +        /* TODO check if synchronization correct */
>>>> 	Result r;
>>>> 	synchronized (txntr) {
>>>> //TODO - check for ACTIVE too?
>>>> @@ -1066,7 +1048,7 @@
>>>>
>>>>        try {
>>>>            // getState and expiration checked atomically
>>>> -            txntr.checkStateActive(); // Throws UnknownLeaseException if state not ACTIVE.
>>>> +            txntr.atomicCheckStateActive(); // throws TransactionException if state not ACTIVE.
>>>>            // State is still active, make it expire.
>>>>            txntr.setExpiration(0);	// Mark as done
>>>>            abort(((Long)tid).longValue(), false);
>>>> Index: src/com/sun/jini/mahalo/TxnManagerImplInitializer.java
>>>> --- src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Locally Modified (Based On LOCAL)
>>>> @@ -38,6 +38,8 @@
>>>> import java.util.HashMap;
>>>> import java.util.Iterator;
>>>> import java.util.Map;
>>>> +import java.util.concurrent.ConcurrentHashMap;
>>>> +import java.util.concurrent.ConcurrentMap;
>>>> import java.util.logging.Level;
>>>> import net.jini.activation.ActivationExporter;
>>>> import net.jini.config.Configuration;
>>>> @@ -64,7 +66,7 @@
>>>>    int taskthreads = 50;
>>>>    long tasktimeout = 1000 * 15;
>>>>    float taskload = 1.0F;
>>>> -    Map<Long, TxnManagerTransaction>  txns = Collections.synchronizedMap(new HashMap<Long, TxnManagerTransaction>());
>>>> +    ConcurrentMap<Long, TxnManagerTransaction>  txns = new ConcurrentHashMap<Long, TxnManagerTransaction>();
>>>>    /* Retrieve values from properties.          */
>>>>    ActivationSystem activationSystem = null;
>>>>    boolean activationPrepared = false;
>>>> Index: src/com/sun/jini/mahalo/TxnManagerTransaction.java
>>>> --- src/com/sun/jini/mahalo/TxnManagerTransaction.java Base (BASE)
>>>> +++ src/com/sun/jini/mahalo/TxnManagerTransaction.java Locally Modified (Based On LOCAL)
>>>> @@ -135,17 +135,17 @@
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private int trstate;
>>>> +    private int trstate; //sync on stateLock
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private long expires;		//expiration time
>>>> +    private long expires;		//expiration time sync on leaseLock
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private LogManager logmgr;
>>>> +    private final LogManager logmgr;
>>>>
>>>>
>>>>   /**
>>>> @@ -180,27 +180,27 @@
>>>>    *
>>>>    * @serial
>>>>    */
>>>> -    private TaskManager threadpool;
>>>> +    private final TaskManager threadpool;
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private WakeupManager wm;
>>>> +    private final WakeupManager wm;
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private TxnSettler settler;
>>>> +    private final TxnSettler settler;
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private Job job;
>>>> +    private Job job; // sync with jobLock
>>>>
>>>>    /**
>>>>     * @serial
>>>>     */
>>>> -    private Uuid uuid;
>>>> +    private final Uuid uuid;
>>>>
>>>>   /**
>>>>    * Interlock for the expiration time since
>>>> @@ -524,12 +524,21 @@
>>>> 	}
>>>>    }
>>>>
>>>> +    public int atomicCheckExpirationIfActive() throws TransactionException {
>>>> +        synchronized (stateLock){
>>>> +            int state = getState();
>>>> +            if (state == ACTIVE&&  !(getExpiration()>  System.currentTimeMillis()))
>>>> +                throw new TransactionException("unknown transaction");
>>>> +            return state;
>>>> +        }
>>>> +    }
>>>> +
>>>>    /**
>>>>     * Atomic check that state is ACTIVE.
>>>>     * @return ACTIVE if lease hasn't expired.
>>>>     * @throws TransactionException otherwise.
>>>>     */
>>>> -    public int checkStateActive() throws TransactionException {
>>>> +    public int atomicCheckStateActive() throws TransactionException {
>>>>        synchronized (stateLock){
>>>>            int state = getState();
>>>>            if ((state == ACTIVE&&  getExpiration()==0) || (state != ACTIVE)) {
>>>> @@ -839,13 +848,15 @@
>>>> 								"ABORTED");
>>>> 		  }
>>>>
>>>> -                  if (getState() != COMMITTED)
>>>> +                  if (getState() != COMMITTED){
>>>> +                      synchronized (jobLock){
>>>>                        throw new
>>>>                            InternalManagerException("TxnManagerTransaction: " +
>>>>                                    "commit: " + job + " got bad state: " +
>>>>                                    TxnConstants.getName(result.intValue()));
>>>> +                      }
>>>> +                  }
>>>>
>>>> -
>>>> 		now = System.currentTimeMillis();
>>>> 		transpired = now - starttime;
>>>>
>>>> Index: src/com/sun/jini/mercury/MailboxImpl.java
>>>> --- src/com/sun/jini/mercury/MailboxImpl.java Base (BASE)
>>>> +++ src/com/sun/jini/mercury/MailboxImpl.java Locally Modified (Based On LOCAL)
>>>> @@ -419,7 +419,7 @@
>>>>    // constructor thread and set to null after starting.
>>>>    private Configuration config;
>>>>    private Throwable thrown;
>>>> -    private volatile boolean started = false;
>>>> +    private boolean started = false;
>>>>
>>>>    ///////////////////////
>>>>    // Activation Methods
>>>> @@ -1071,8 +1071,8 @@
>>>> //    } // End doInit()
>>>> //
>>>>    public void start() throws Exception {
>>>> -        if (started) return;
>>>>        concurrentObj.writeLock();
>>>> +        if (started) return;
>>>>        started = true; // mutual exclusion
>>>>        try {
>>>>            if (thrown != null) throw thrown;
>>>> Index: src/com/sun/jini/outrigger/EventRegistrationWatcher.java
>>>> --- src/com/sun/jini/outrigger/EventRegistrationWatcher.java Base (BASE)
>>>> +++ src/com/sun/jini/outrigger/EventRegistrationWatcher.java Locally Modified (Based On LOCAL)
>>>> @@ -240,7 +240,7 @@
>>>>     * @return The unique identifier associated with this
>>>>     * watcher.
>>>>     */
>>>> -    public Uuid getCookie() {
>>>> +    public synchronized Uuid getCookie() {
>>>> 	return cookie;
>>>>    }
>>>>
>>>> Index: src/com/sun/jini/outrigger/OutriggerServerImpl.java
>>>> --- src/com/sun/jini/outrigger/OutriggerServerImpl.java Base (BASE)
>>>> +++ src/com/sun/jini/outrigger/OutriggerServerImpl.java Locally Modified (Based On LOCAL)
>>>> @@ -647,6 +647,7 @@
>>>>        if (except != null) throw except;
>>>>        try {
>>>>            // This takes a while the first time, so let's get it going
>>>> +            txnMonitor.start();
>>>>            starter.start();
>>>>
>>>>            // Get store from configuration
>>>> Index: src/com/sun/jini/outrigger/StorableEventWatcher.java
>>>> --- src/com/sun/jini/outrigger/StorableEventWatcher.java Base (BASE)
>>>> +++ src/com/sun/jini/outrigger/StorableEventWatcher.java Locally Modified (Based On LOCAL)
>>>> @@ -36,7 +36,7 @@
>>>>    implements StorableResource
>>>> {
>>>>    /** The listener that should be notified of matches */
>>>> -    private StorableReference listener;
>>>> +    private volatile StorableReference listener;
>>>>
>>>>    /**
>>>>     * Used during log recovery to create a mostly empty
>>>> @@ -115,7 +115,7 @@
>>>>     * @param expired<code>true</code>  if being called from
>>>>     *<code>removeIfExpired</code>  and false otherwise.
>>>>     */
>>>> -    void cleanup(TemplateHandle owner, boolean expired) {
>>>> +    synchronized void cleanup(TemplateHandle owner, boolean expired) {
>>>> 	if (expired)
>>>> 	    owner.getServer().scheduleCancelOp(cookie);
>>>> 	else
>>>> @@ -126,7 +126,7 @@
>>>>    /**
>>>>     * Store the persistent fields
>>>>     */
>>>> -    public void store(ObjectOutputStream out) throws IOException {
>>>> +    public synchronized void store(ObjectOutputStream out) throws IOException {
>>>> 	cookie.write(out);
>>>> 	out.writeLong(expiration);
>>>> 	out.writeLong(eventID);
>>>> @@ -137,7 +137,7 @@
>>>>    /**
>>>>     * Restore the persistent fields
>>>>     */
>>>> -    public void restore(ObjectInputStream in)
>>>> +    public synchronized void restore(ObjectInputStream in)
>>>> 	throws IOException, ClassNotFoundException
>>>>    {
>>>> 	cookie = UuidFactory.read(in);
>>>> Index: src/com/sun/jini/outrigger/TxnMonitor.java
>>>> --- src/com/sun/jini/outrigger/TxnMonitor.java Base (BASE)
>>>> +++ src/com/sun/jini/outrigger/TxnMonitor.java Locally Modified (Based On LOCAL)
>>>> @@ -51,8 +51,8 @@
>>>>     * @see #pending
>>>>     */
>>>>    private static class ToMonitor {
>>>> -	QueryWatcher	query;         // query governing interest in txns
>>>> -	Collection	txns;	       // the transactions to monitor
>>>> +	final QueryWatcher	query;         // query governing interest in txns
>>>> +	final Collection	txns;	       // the transactions to monitor
>>>>
>>>> 	ToMonitor(QueryWatcher query, Collection txns) {
>>>> 	    this.query = query;
>>>> @@ -71,7 +71,7 @@
>>>>     * @see OutriggerServerImpl#getMatch
>>>>     */
>>>>    // @see #ToMonitor
>>>> -    private LinkedList pending = new LinkedList();
>>>> +    private final LinkedList pending = new LinkedList();
>>>>
>>>>    /** wakeup manager for<code>TxnMonitorTask</code>s */
>>>>    private final WakeupManager wakeupMgr =
>>>> @@ -80,21 +80,23 @@
>>>>    /**
>>>>     * The manager for<code>TxnMonitorTask</code>  objects.
>>>>     */
>>>> -    private TaskManager taskManager;
>>>> +    private final TaskManager taskManager;
>>>>
>>>>    /**
>>>>     * The space we belong to.  Needed for aborts.
>>>>     */
>>>> -    private OutriggerServerImpl	space;
>>>> +    private final OutriggerServerImpl	space;
>>>>
>>>>    /**
>>>>     * The thread running us.
>>>>     */
>>>> -    private Thread ourThread;
>>>> +    private final Thread ourThread;
>>>>
>>>>    /** Set when we are told to stop */
>>>> -    private boolean die = false;
>>>> +    private volatile boolean die = false;
>>>>
>>>> +    private volatile boolean started = false;
>>>> +
>>>>    /** Logger for logging transaction related information */
>>>>    private static final Logger logger =
>>>> 	Logger.getLogger(OutriggerServerImpl.txnLoggerName);
>>>> @@ -115,8 +117,15 @@
>>>>
>>>>        ourThread = new Thread(this, "TxnMonitor");
>>>> 	ourThread.setDaemon(true);
>>>> +//        ourThread.start();
>>>> +    }
>>>> +
>>>> +    public void start(){
>>>> +        synchronized (this){
>>>>        ourThread.start();
>>>> +            started = true;
>>>>    }
>>>> +    }
>>>>
>>>>    public void destroy() {
>>>>        taskManager.terminate();
>>>> @@ -128,7 +137,7 @@
>>>> 	}
>>>>
>>>>        try {
>>>> -	    ourThread.join();
>>>> +	    if (started) ourThread.join();
>>>> 	} catch(InterruptedException ie) {
>>>> 	    // ignore
>>>> 	}
>>>> Index: src/com/sun/jini/outrigger/TypeTree.java
>>>> --- src/com/sun/jini/outrigger/TypeTree.java Base (BASE)
>>>> +++ src/com/sun/jini/outrigger/TypeTree.java Locally Modified (Based On LOCAL)
>>>> @@ -39,7 +39,7 @@
>>>> */
>>>> class TypeTree {
>>>>    /** For each type, a vector of known subtypes */
>>>> -    private Hashtable subclasses = new Hashtable();
>>>> +    private final Hashtable<String,Vector>  subclasses = new Hashtable<String,Vector>();
>>>>
>>>>    /**
>>>>     * A generator used to randomize the order of iterator returns
>>>> @@ -57,8 +57,10 @@
>>>>     * Return the vector of subclasses for the given class.
>>>>     */
>>>>    private Vector classVector(String whichClass) {
>>>> +        synchronized (subclasses){
>>>> 	return (Vector) subclasses.get(whichClass);
>>>>    }
>>>> +    }
>>>>
>>>>    /**
>>>>     * An iterator that will walk through a list of known types.
>>>> Index: src/com/sun/jini/thread/RetryTask.java
>>>> --- src/com/sun/jini/thread/RetryTask.java Base (BASE)
>>>> +++ src/com/sun/jini/thread/RetryTask.java Locally Modified (Based On LOCAL)
>>>> @@ -64,7 +64,7 @@
>>>> import com.sun.jini.thread.WakeupManager.Ticket;
>>>>
>>>> public abstract class RetryTask implements TaskManager.Task, TimeConstants {
>>>> -    private TaskManager	  manager;	// the TaskManager for this task
>>>> +    private final TaskManager	  manager;	// the TaskManager for this task
>>>>    private RetryTime	  retry;	// the retry object for this task
>>>>    private boolean	  cancelled;	// have we been cancelled?
>>>>    private boolean	  complete;	// have we completed successfully?
>>>> @@ -72,7 +72,7 @@
>>>>    private long	  startTime;	// the time when we were created or
>>>>                                        //   last reset
>>>>    private int		  attempt;	// the current attempt number
>>>> -    private WakeupManager wakeup;       // WakeupManager for retry scheduling
>>>> +    private final WakeupManager wakeup;       // WakeupManager for retry scheduling
>>>>
>>>>    /**
>>>>     * Default delay backoff times.  These are converted from
>>>> @@ -91,7 +91,7 @@
>>>>    };
>>>>
>>>>    /** Logger for this class */
>>>> -    private static final Logger logger =
>>>> +    protected static final Logger logger =
>>>> 	Logger.getLogger("com.sun.jini.thread.RetryTask");
>>>>
>>>>    /**
>>>> @@ -128,7 +128,14 @@
>>>> 		return;			// do nothing
>>>> 	}
>>>>
>>>> -	boolean success = tryOnce();
>>>> +	boolean success = false;
>>>> +        try {
>>>> +            success = tryOnce();
>>>> +        } catch (Throwable t){
>>>> +            t.printStackTrace(System.err);
>>>> +            if (t instanceof Error) throw (Error) t;
>>>> +            if (t instanceof RuntimeException) throw (RuntimeException) t;
>>>> +        }
>>>>
>>>> 	synchronized (this) {
>>>> 	    if (!success) {		// if at first we don't succeed ...
>>>> Index: src/com/sun/jini/thread/TaskManager.java
>>>> --- src/com/sun/jini/thread/TaskManager.java Base (BASE)
>>>> +++ src/com/sun/jini/thread/TaskManager.java Locally Modified (Based On LOCAL)
>>>> @@ -22,6 +22,7 @@
>>>> import java.util.Collections;
>>>> import java.util.Iterator;
>>>> import java.util.List;
>>>> +import java.util.concurrent.CopyOnWriteArrayList;
>>>> import java.util.logging.Level;
>>>> import java.util.logging.Logger;
>>>>
>>>> @@ -77,13 +78,13 @@
>>>> 	Logger.getLogger("com.sun.jini.thread.TaskManager");
>>>>
>>>>    /** Active and pending tasks */
>>>> -    protected final ArrayList tasks = new ArrayList();
>>>> +    protected final ArrayList tasks = new ArrayList(); //sync on this
>>>>    /** Index of the first pending task; all earlier tasks are active */
>>>> -    protected int firstPending = 0;
>>>> +    protected int firstPending = 0;//sync on this
>>>>    /** Read-only view of tasks */
>>>> -    protected final List roTasks = Collections.unmodifiableList(tasks);
>>>> +    protected final List roTasks = Collections.unmodifiableList(tasks); // sync on this
>>>>    /** Active threads */
>>>> -    protected final List threads = new ArrayList();
>>>> +    protected final List threads = new ArrayList(); //sync on this
>>>>    /** Maximum number of threads allowed */
>>>>    protected final int maxThreads;
>>>>    /** Idle time before a thread should exit */
>>>> @@ -91,7 +92,7 @@
>>>>    /** Threshold for creating new threads */
>>>>    protected final float loadFactor;
>>>>    /** True if manager has been terminated */
>>>> -    protected boolean terminated = false;
>>>> +    protected boolean terminated = false; //sync on this
>>>>
>>>>    /**
>>>>     * Create a task manager with maxThreads = 10, timeout = 15 seconds,
>>>> @@ -256,7 +257,7 @@
>>>>
>>>>    /** Return all pending tasks.  A new list is returned each time. */
>>>>    public synchronized ArrayList getPending() {
>>>> -	ArrayList tc = (ArrayList)tasks.clone();
>>>> +	ArrayList tc = new ArrayList(tasks);
>>>> 	for (int i = firstPending; --i>= 0; ) {
>>>> 	    tc.remove(0);
>>>> 	}
>>>> @@ -271,7 +272,7 @@
>>>>    private class TaskThread extends Thread {
>>>>
>>>> 	/** The task being run, if any */
>>>> -	public Task task = null;
>>>> +	public Task task = null; // sync access on TaskManager.this
>>>>
>>>> 	public TaskThread() {
>>>> 	    super("task");
>>>> @@ -303,6 +304,7 @@
>>>>
>>>> 	public void run() {
>>>> 	    while (true) {
>>>> +                Task tsk = null;
>>>> 		synchronized (TaskManager.this) {
>>>> 		    if (terminated)
>>>> 			return;
>>>> @@ -327,9 +329,10 @@
>>>> 			    return;
>>>> 			}
>>>> 		    }
>>>> +                    tsk = task;
>>>> 		}
>>>> 		try {
>>>> -		    task.run();
>>>> +		    tsk.run();
>>>> 		} catch (Throwable t) {
>>>> 		    try {
>>>> 			logger.log(Level.WARNING, "Task.run exception", t);
>>>> Index: src/com/sun/jini/thread/WakeupManager.java
>>>> --- src/com/sun/jini/thread/WakeupManager.java Base (BASE)
>>>> +++ src/com/sun/jini/thread/WakeupManager.java Locally Modified (Based On LOCAL)
>>>> @@ -493,7 +493,7 @@
>>>>     * Assumes the caller holds the lock on contents.
>>>>     */
>>>>    private void checkHead() {
>>>> -	assert Thread.holdsLock(contents);
>>>> +        synchronized (contents){
>>>> 	final Ticket oldHead = head;
>>>>
>>>> 	if (contents.isEmpty())
>>>> @@ -507,6 +507,7 @@
>>>> 	// needs to wake up and change its sleep time.
>>>> 	contents.notifyAll();
>>>>    }
>>>> +    }
>>>>
>>>>    /**
>>>>     * Return whether the queue is currently empty.
>>>> Index: src/net/jini/lookup/JoinManager.java
>>>> --- src/net/jini/lookup/JoinManager.java Base (BASE)
>>>> +++ src/net/jini/lookup/JoinManager.java Locally Modified (Based On LOCAL)
>>>> @@ -563,10 +563,11 @@
>>>>    private class ProxyRegTask extends RetryTask {
>>>>        private final long[] sleepTime = { 5*1000, 10*1000, 15*1000,
>>>>                                          20*1000, 25*1000, 30*1000 };
>>>> -        protected int tryIndx  = 0;
>>>> -        protected int nRetries = 0;
>>>> -        protected ProxyReg proxyReg;
>>>> -        protected int seqN;
>>>> +        // volatile fields only mutated while synchronized on proxyReg.taskList
>>>> +        private volatile int tryIndx  = 0;
>>>> +        private volatile int nRetries = 0;
>>>> +        private final ProxyReg proxyReg;
>>>> +        private volatile int seqN;
>>>>
>>>>        /** Basic constructor; simply stores the input parameters */
>>>>        ProxyRegTask(ProxyReg proxyReg, int seqN) {
>>>> @@ -611,10 +612,11 @@
>>>>                        if( !proxyReg.taskList.isEmpty() ) {
>>>>                            proxyReg.taskList.remove(0);
>>>>                        }//endif
>>>> -                    }//end sync
>>>>                    /* reset the retry info for the next task in the list */
>>>>                    tryIndx  = 0;
>>>>                    nRetries = 0;
>>>> +                    }//end sync
>>>> +
>>>>                } catch (Exception e) {
>>>>                    return stopTrying(e);
>>>>                }
>>>> @@ -627,8 +629,10 @@
>>>>         */
>>>>        public long retryTime() {
>>>> 	    long nextTryTime = System.currentTimeMillis() + sleepTime[tryIndx];
>>>> +            synchronized (proxyReg.taskList){
>>>> 	    if(tryIndx<  sleepTime.length-1)  tryIndx++;//don't go past end
>>>>            nRetries++;
>>>> +            }
>>>>            return nextTryTime;
>>>>        }//end retryTime
>>>>
>>>> @@ -737,7 +741,7 @@
>>>>    private abstract class JoinTask {
>>>>
>>>>        /** Data structure referencing the task's associated lookup service */
>>>> -        protected ProxyReg proxyReg;
>>>> +        protected final ProxyReg proxyReg;
>>>>
>>>>        /** Basic constructor; simply stores the input parameters */
>>>>        JoinTask(ProxyReg proxyReg) {
>>>> @@ -758,7 +762,7 @@
>>>>         *  must not change during the registration process performed in
>>>>         *  this this task.
>>>>         */
>>>> -        Entry[] regAttrs;
>>>> +        final Entry[] regAttrs;
>>>>
>>>>        /** Constructor that associates this task with the lookup service
>>>>         *  referenced in the given<code>ProxyReg</code>  parameter.
>>>> @@ -889,9 +893,10 @@
>>>>         */
>>>>        public void run() {
>>>>            logger.finest("JoinManager -->  DiscardProxyTask started");
>>>> -            if( (proxyReg != null)&&  (proxyReg.serviceLease != null) ) {
>>>> +            Lease svcLease = proxyReg != null ? proxyReg.serviceLease : null;
>>>> +            if( svcLease != null ) {
>>>>                try {
>>>> -                    proxyReg.serviceLease.cancel();
>>>> +                    svcLease.cancel();
>>>>                } catch (Exception e) { /*ignore*/ }
>>>>            }//endif
>>>>            logger.finest("JoinManager - DiscardProxyTask completed");
>>>> @@ -1140,31 +1145,34 @@
>>>>        /** The<code>ProxyRegTask</code>  that instantiated this
>>>>         *<code>ProxyReg</code>.
>>>>         */
>>>> -        public ProxyRegTask proxyRegTask;
>>>> +        volatile ProxyRegTask proxyRegTask;
>>>>        /** The<i>prepared</i>  proxy to the lookup service referenced by
>>>>         *  this class, and with which this join manager's service will be
>>>>         *  registered.
>>>>         */
>>>> -	public ServiceRegistrar proxy;
>>>> +	final ServiceRegistrar proxy;
>>>>        /** The<i>prepared</i>  registration proxy returned by this class'
>>>>         *  associated lookup service when this join manager registers its
>>>>         *  associated service.
>>>> +         *
>>>> +         * Access to reference synchronized on joinSet, but not referent
>>>> +         * as it has foreign remote methods.
>>>>         */
>>>> -	public ServiceRegistration srvcRegistration = null;
>>>> +	ServiceRegistration srvcRegistration = null;
>>>>        /* The<i>prepared</i>  proxy to the lease on the registration of this
>>>>         * join manager's service with the this class' associated lookup
>>>>         * service.
>>>>         */
>>>> -	public Lease serviceLease = null;
>>>> +	volatile Lease serviceLease = null;
>>>>        /** The set of sub-tasks that are to be executed in order for the
>>>>         *  lookup service associated with the current instance of this class.
>>>>         */
>>>> -        public List taskList = new ArrayList(1);
>>>> +        final List taskList = new ArrayList(1);
>>>>        /** The instance of<code>DiscLeaseListener</code>  that is registered
>>>>         *  with the lease renewal manager that handles the lease of this join
>>>>         *  manger's service.
>>>>         */
>>>> -	private DiscLeaseListener dListener = new DiscLeaseListener();
>>>> +	private final DiscLeaseListener dListener = new DiscLeaseListener();
>>>>
>>>>        /** Constructor that associates this class with the lookup service
>>>>         *  referenced in the given<code>ProxyReg</code>  parameter.
>>>> @@ -1236,19 +1244,19 @@
>>>>                throw e; //rethrow the exception since proxy may be unusable
>>>>            }
>>>>            /* Retrieve and prepare the proxy to the service lease */
>>>> -            serviceLease = tmpSrvcRegistration.getLease();
>>>> +            Lease svcLease = tmpSrvcRegistration.getLease();
>>>>            try {
>>>> -                serviceLease =
>>>> -                       (Lease)serviceLeasePreparer.prepareProxy(serviceLease);
>>>> +                this.serviceLease =
>>>> +                       (Lease)serviceLeasePreparer.prepareProxy(svcLease);
>>>>                logger.finest("JoinManager - service lease proxy prepared");
>>>>            } catch(Exception e) {
>>>> 		LogUtil.logThrow(logger, Level.WARNING, ProxyReg.class,
>>>> 		    	"register", "JoinManager - failure during " +
>>>> 		    	"preparation of service lease proxy: {0}",
>>>> -		    	new Object[] { serviceLease }, e);
>>>> +		    	new Object[] { svcLease }, e);
>>>>                throw e; //rethrow the exception since proxy may be unusable
>>>>            }
>>>> -            leaseRenewalMgr.renewUntil(serviceLease, Lease.FOREVER,
>>>> +            leaseRenewalMgr.renewUntil(svcLease, Lease.FOREVER,
>>>>                                       renewalDuration, dListener);
>>>>            ServiceID tmpID = null;
>>>>            synchronized(joinSet) {
>>>> @@ -1272,7 +1280,11 @@
>>>>         *  addition to that service's current set of attributes.
>>>>         */
>>>>        public void addAttributes(Entry[] attSet) throws Exception {
>>>> -            srvcRegistration.addAttributes(attSet);
>>>> +            ServiceRegistration sr;
>>>> +            synchronized (joinSet){
>>>> +                sr = srvcRegistration;
>>>> +            }
>>>> +            sr.addAttributes(attSet);
>>>> 	}//end ProxyReg.addAttributes
>>>>
>>>>        /** With respect to the lookup service referenced in this class
>>>> @@ -1285,7 +1297,11 @@
>>>>        public void modifyAttributes(Entry[] templ, Entry[] attSet)
>>>>                                                             throws Exception
>>>>        {
>>>> -            srvcRegistration.modifyAttributes(templ, attSet);
>>>> +            ServiceRegistration sr;
>>>> +            synchronized (joinSet){
>>>> +               sr = srvcRegistration;
>>>> +            }
>>>> +            sr.modifyAttributes(templ, attSet);
>>>> 	}//end ProxyReg.modifyAttributes		
>>>>
>>>>        /** With respect to the lookup service referenced in this class
>>>> @@ -1294,7 +1310,11 @@
>>>>         *  set of attributes.
>>>>         */
>>>>        public void setAttributes(Entry[] attSet) throws Exception {
>>>> -            srvcRegistration.setAttributes(attSet);
>>>> +            ServiceRegistration sr;
>>>> +            synchronized (joinSet){
>>>> +               sr = srvcRegistration;
>>>> +            }
>>>> +            sr.setAttributes(attSet);
>>>> 	}//end ProxyReg.setAttributes
>>>>
>>>>        /** Convenience method that encapsulates appropriate behavior when
>>>> @@ -1432,7 +1452,7 @@
>>>>     *  which each task is associated). This field contains the value of
>>>>     *  the sequence number assigned to the most recently created task.
>>>>     */
>>>> -    private int taskSeqN = 0;
>>>> +    private int taskSeqN = 0; // access sync on taskList
>>>>    /** Task manager for the various tasks executed by this join manager.
>>>>     *  On the first attempt to execute any task is managed by this
>>>>     *<code>TaskManager</code>  so that the number of concurrent threads
>>>> @@ -1442,9 +1462,9 @@
>>>>     *  "backoff strategy") - the re-execution of each failed task in this
>>>>     *<code>TaskManager</code>.
>>>>     */
>>>> -    private TaskManager taskMgr;
>>>> +    private final TaskManager taskMgr;
>>>>    /** Maximum number of times a failed task is allowed to be re-executed. */
>>>> -    private int maxNRetries = 6;
>>>> +    private final int maxNRetries;
>>>>    /** Wakeup manager for the various tasks executed by this join manager.
>>>>     *  After an initial failure of any task executed by this join manager,
>>>>     *  the failed task is managed by this<code>WakeupManager</code>; which
>>>> @@ -1456,22 +1476,22 @@
>>>>     *  join manager is requested, all tasks scheduled for retry by this
>>>>     *  wakeup manager can be cancelled.
>>>>     */
>>>> -    private WakeupManager wakeupMgr;
>>>> +    private final WakeupManager wakeupMgr;
>>>>    /** Contains the reference to the service that is to be registered with
>>>>     *  all of the desired lookup services referenced by<code>discMgr</code>.
>>>>     */
>>>> -    private ServiceItem serviceItem;
>>>> +    private final ServiceItem serviceItem;
>>>>    /** Contains the attributes with which to associate the service in each
>>>>     *  of the lookup services with which this join manager registers the
>>>>     *  service.
>>>>     */
>>>> -    private Entry[] lookupAttr = null;
>>>> +    private Entry[] lookupAttr = null; // access sync on joinSet
>>>>    /** Contains the listener -- instantiated by the entity that constructs
>>>>     *  this join manager -- that will receive an event containing the
>>>>     *  service ID assigned to this join manager's service by one of the
>>>>     *  lookup services with which that service is registered.
>>>>     */
>>>> -    private ServiceIDListener callback;
>>>> +    private final ServiceIDListener callback;
>>>>    /** Contains elements of type<code>ProxyReg</code>  where each element
>>>>     *  references a proxy to one of the lookup services with which this
>>>>     *  join manager's service is registered.
>>>> @@ -1480,22 +1500,22 @@
>>>>    /** Contains the discovery manager that discovers the lookup services
>>>>     *  with which this join manager will register its associated service.
>>>>     */
>>>> -    private DiscoveryManagement discMgr = null;
>>>> +    private final DiscoveryManagement discMgr;
>>>>    /** Contains the discovery listener registered by this join manager with
>>>>     *  the discovery manager so that this join manager is notified whenever
>>>>     *  one of the desired lookup services is discovered or discarded.
>>>>     */
>>>> -    private DiscMgrListener discMgrListener = new DiscMgrListener();
>>>> +    private final DiscMgrListener discMgrListener ;
>>>>    /** Flag that indicate whether the discovery manager employed by this
>>>>     *  join manager was created by this join manager itself, or by the
>>>>     *  entity that constructed this join manager.
>>>>     */
>>>> -    private boolean bCreateDiscMgr = false;
>>>> +    private final boolean bCreateDiscMgr;
>>>>    /** Contains the lease renewal manager that renews all of the leases
>>>>     *  this join manager's service holds with each lookup service with which
>>>>     *  it has been registered.
>>>>     */
>>>> -    private LeaseRenewalManager leaseRenewalMgr = null;
>>>> +    private final LeaseRenewalManager leaseRenewalMgr;
>>>>    /** The value to use as the<code>renewDuration</code>  parameter
>>>>     *  when invoking the lease renewal manager's<code>renewUntil</code>
>>>>     *  method to add a service lease to manage. This value represents,
>>>> @@ -1505,22 +1525,22 @@
>>>>     *  is up, and lease expirations will occur sooner when the service
>>>>     *  goes down.
>>>>     */
>>>> -    private long renewalDuration = Lease.FOREVER;
>>>> +    private final long renewalDuration;
>>>>    /** Flag that indicates if this join manager has been terminated. */
>>>> -    private volatile boolean bTerminated = false;
>>>> +    private boolean bTerminated = false; // All access sync on this.
>>>>    /* Preparer for the proxies to the lookup services that are discovered
>>>>     * and used by this utility.
>>>>     */
>>>> -    private ProxyPreparer registrarPreparer;
>>>> +    private final ProxyPreparer registrarPreparer;
>>>>    /* Preparer for the proxies to the registrations returned to this utility
>>>>     * upon registering the service with each discovered lookup service.
>>>>     */
>>>> -    private ProxyPreparer registrationPreparer;
>>>> +    private final ProxyPreparer registrationPreparer;
>>>>    /* Preparer for the proxies to the leases returned to this utility through
>>>>     * the registrations with each discovered lookup service with which this
>>>>     * utility has registered the service.
>>>>     */
>>>> -    private ProxyPreparer serviceLeasePreparer;
>>>> +    private final ProxyPreparer serviceLeasePreparer;
>>>>
>>>>    /**
>>>>     * Constructs an instance of this class that will register the given
>>>> @@ -1619,11 +1639,8 @@
>>>> 			DiscoveryManagement discoveryMgr,
>>>> 			LeaseRenewalManager leaseMgr)    throws IOException
>>>>    {
>>>> -        discMgr = discoveryMgr;
>>>> -        try {
>>>> -           createJoinManager(null, serviceProxy, attrSets, callback, leaseMgr,
>>>> -                             EmptyConfiguration.INSTANCE);
>>>> -        } catch(ConfigurationException e) { /* swallow this exception */ }
>>>> +           this(serviceProxy, attrSets, null, callback,
>>>> +                 getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy));
>>>>    }//end constructor
>>>>
>>>>    /**
>>>> @@ -1737,9 +1754,10 @@
>>>>                        Configuration config)
>>>>                                    throws IOException, ConfigurationException
>>>>    {
>>>> -        discMgr = discoveryMgr;
>>>> -        createJoinManager(null, serviceProxy, attrSets,
>>>> -                          callback, leaseMgr, config);
>>>> +
>>>> +        this(serviceProxy, attrSets, null, callback,
>>>> +            getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
>>>> +        );
>>>>    }//end constructor
>>>>
>>>>    /**
>>>> @@ -1797,12 +1815,9 @@
>>>> 			DiscoveryManagement discoveryMgr,
>>>> 			LeaseRenewalManager leaseMgr)    throws IOException
>>>>    {
>>>> -        discMgr = discoveryMgr;
>>>> -        try {
>>>> -           createJoinManager(serviceID, serviceProxy, attrSets,
>>>> -                             (ServiceIDListener)null, leaseMgr,
>>>> -                             EmptyConfiguration.INSTANCE);
>>>> -        } catch(ConfigurationException e) { /* swallow this exception */ }
>>>> +       this(serviceProxy, attrSets, serviceID, null,
>>>> +             getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy)
>>>> +       );
>>>>    }//end constructor
>>>>
>>>>    /**
>>>> @@ -1877,9 +1892,9 @@
>>>>                        Configuration config)
>>>>                                    throws IOException, ConfigurationException
>>>>    {
>>>> -        discMgr = discoveryMgr;
>>>> -        createJoinManager(serviceID, serviceProxy, attrSets,
>>>> -                          (ServiceIDListener)null, leaseMgr, config);
>>>> +        this(serviceProxy, attrSets, serviceID, null,
>>>> +             getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
>>>> +       );
>>>>    }//end constructor
>>>>
>>>>    /**
>>>> @@ -2464,44 +2479,113 @@
>>>>        replaceRegistrationDo(serviceProxy, attrSets, true);
>>>>    }//end replaceRegistration
>>>>
>>>> -    /** Convenience method invoked by the constructors of this class that
>>>> -     *  uses the given<code>Configuration</code>  to initialize the current
>>>> -     *  instance of this utility, and initiates all join processing for
>>>> -     *  the given parameters. This method handles the various configurations
>>>> -     *  allowed by the different constructors.
>>>> +    private static class Conf{
>>>> +        ProxyPreparer registrarPreparer;
>>>> +        ProxyPreparer registrationPreparer;
>>>> +        ProxyPreparer serviceLeasePreparer;
>>>> +        TaskManager taskManager;
>>>> +        WakeupManager wakeupManager;
>>>> +        Integer maxNretrys;
>>>> +        LeaseRenewalManager leaseRenewalManager;
>>>> +        Long renewalDuration;
>>>> +        DiscoveryManagement discoveryMgr;
>>>> +        boolean bcreateDisco;
>>>> +
>>>> +        Conf (  ProxyPreparer registrarPreparer,
>>>> +                ProxyPreparer registrationPreparer,
>>>> +                ProxyPreparer serviceLeasePreparer,
>>>> +                TaskManager taskManager,
>>>> +                WakeupManager wakeupManager,
>>>> +                Integer maxNretrys,
>>>> +                LeaseRenewalManager leaseRenewalManager,
>>>> +                Long renewalDuration,
>>>> +                DiscoveryManagement discoveryMgr,
>>>> +                boolean bcreateDisco)
>>>> +        {
>>>> +            this.registrarPreparer = registrarPreparer;
>>>> +            this.registrationPreparer = registrationPreparer;
>>>> +            this.serviceLeasePreparer = serviceLeasePreparer;
>>>> +            this.taskManager = taskManager;
>>>> +            this.wakeupManager = wakeupManager;
>>>> +            this.maxNretrys = maxNretrys;
>>>> +            this.leaseRenewalManager = leaseRenewalManager;
>>>> +            this.renewalDuration = renewalDuration;
>>>> +            this.discoveryMgr = discoveryMgr;
>>>> +            this.bcreateDisco = bcreateDisco;
>>>> +        }
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * This method is for constructors that use an empty configuration.
>>>> +     *
>>>> +     * @param config
>>>> +     * @param leaseMgr
>>>> +     * @param discoveryMgr
>>>> +     * @param serviceProxy
>>>> +     * @return
>>>> +     * @throws IOException
>>>> +     * @throws NullPointerException
>>>> +     * @throws IllegalArgumentException
>>>>     */
>>>> -    private void createJoinManager(ServiceID serviceID,
>>>> -                                   Object serviceProxy,
>>>> -                                   Entry[] attrSets,
>>>> -                                   ServiceIDListener callback,
>>>> +    private static Conf getConf(    Configuration config,
>>>>                                   LeaseRenewalManager leaseMgr,
>>>> -                                   Configuration config)
>>>> -                                    throws IOException, ConfigurationException
>>>> +                                    DiscoveryManagement discoveryMgr,
>>>> +                                    Object serviceProxy)
>>>> +            throws IOException, NullPointerException, IllegalArgumentException {
>>>> +        try {
>>>> +            return getConfig(config, leaseMgr, discoveryMgr, serviceProxy);
>>>> +        } catch (ConfigurationException e){
>>>> +            throw new IOException("Configuration problem during construction", e);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * Gets the configuration and throws any exceptions.
>>>> +     *
>>>> +     * This static method guards against finalizer attacks and allows fields
>>>> +     * to be final.
>>>> +     *
>>>> +     * @param config
>>>> +     * @param leaseMgr
>>>> +     * @param discoveryMgr
>>>> +     * @param serviceProxy
>>>> +     * @return
>>>> +     * @throws IOException
>>>> +     * @throws ConfigurationException
>>>> +     * @throws NullPointerException
>>>> +     * @throws IllegalArgumentException
>>>> +     */
>>>> +    private static Conf getConfig(  Configuration config,
>>>> +                                    LeaseRenewalManager leaseMgr,
>>>> +                                    DiscoveryManagement discoveryMgr,
>>>> +                                    Object serviceProxy)
>>>> +            throws IOException, ConfigurationException, NullPointerException,
>>>> +            IllegalArgumentException
>>>>    {
>>>> 	if(!(serviceProxy instanceof java.io.Serializable)) {
>>>>            throw new IllegalArgumentException
>>>>                                       ("serviceProxy must be Serializable");
>>>> 	}//endif
>>>> -
>>>>        /* Retrieve configuration items if applicable */
>>>>        if(config == null)  throw new NullPointerException("config is null");
>>>>        /* Proxy preparers */
>>>> -        registrarPreparer = (ProxyPreparer)config.getEntry
>>>> +        ProxyPreparer registrarPreparer = (ProxyPreparer)config.getEntry
>>>>                                                   (COMPONENT_NAME,
>>>>                                                    "registrarPreparer",
>>>>                                                    ProxyPreparer.class,
>>>>                                                    new BasicProxyPreparer());
>>>> -        registrationPreparer = (ProxyPreparer)config.getEntry
>>>> +        ProxyPreparer registrationPreparer = (ProxyPreparer)config.getEntry
>>>>                                                   (COMPONENT_NAME,
>>>>                                                    "registrationPreparer",
>>>>                                                    ProxyPreparer.class,
>>>>                                                    new BasicProxyPreparer());
>>>> -        serviceLeasePreparer = (ProxyPreparer)config.getEntry
>>>> +        ProxyPreparer serviceLeasePreparer = (ProxyPreparer)config.getEntry
>>>>                                                   (COMPONENT_NAME,
>>>>                                                    "serviceLeasePreparer",
>>>>                                                    ProxyPreparer.class,
>>>>                                                    new BasicProxyPreparer());
>>>>        /* Task manager */
>>>> +        TaskManager taskMgr;
>>>>        try {
>>>>            taskMgr = (TaskManager)config.getEntry(COMPONENT_NAME,
>>>>                                                   "taskManager",
>>>> @@ -2510,6 +2594,7 @@
>>>>            taskMgr = new TaskManager(MAX_N_TASKS,(15*1000),1.0f);
>>>>        }
>>>>        /* Wakeup manager */
>>>> +        WakeupManager wakeupMgr;
>>>>        try {
>>>>            wakeupMgr = (WakeupManager)config.getEntry(COMPONENT_NAME,
>>>>                                                       "wakeupManager",
>>>> @@ -2519,57 +2604,84 @@
>>>>                                    (new WakeupManager.ThreadDesc(null,true));
>>>>        }
>>>>        /* Max number of times to re-schedule tasks in thru wakeup manager */
>>>> -        maxNRetries = ((Integer)config.getEntry
>>>> +        Integer maxNRetries = ((Integer)config.getEntry
>>>>                                        (COMPONENT_NAME,
>>>>                                         "wakeupRetries",
>>>>                                         int.class,
>>>> -                                         Integer.valueOf(maxNRetries))).intValue();
>>>> -        if(attrSets == null) {
>>>> -            lookupAttr = new Entry[0];
>>>> -        } else {
>>>> -            attrSets = (Entry[])attrSets.clone();
>>>> -            LookupAttributes.check(attrSets,false);//null elements NOT ok
>>>> -            lookupAttr = attrSets;
>>>> -        }//endif
>>>> -	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
>>>> +                                         Integer.valueOf(6))).intValue();
>>>>        /* Lease renewal manager */
>>>> -        leaseRenewalMgr = leaseMgr;
>>>> -	if(leaseRenewalMgr == null) {
>>>> +	if(leaseMgr == null) {
>>>>            try {
>>>> -                leaseRenewalMgr = (LeaseRenewalManager)config.getEntry
>>>> +                leaseMgr = (LeaseRenewalManager)config.getEntry
>>>>                                                  (COMPONENT_NAME,
>>>>                                                   "leaseManager",
>>>>                                                   LeaseRenewalManager.class);
>>>>            } catch(NoSuchEntryException e) { /* use default */
>>>> -                leaseRenewalMgr = new LeaseRenewalManager(config);
>>>> +                leaseMgr = new LeaseRenewalManager(config);
>>>>            }
>>>>        }//endif
>>>> -        renewalDuration = ((Long)config.getEntry
>>>> +        Long renewalDuration = ((Long)config.getEntry
>>>>                                      (COMPONENT_NAME,
>>>>                                       "maxLeaseDuration",
>>>>                                       long.class,
>>>> -                                       Long.valueOf(renewalDuration))).longValue();
>>>> +                                       Long.valueOf(Lease.FOREVER))).longValue();
>>>>        if( (renewalDuration == 0) || (renewalDuration<  Lease.ANY) ) {
>>>>            throw new ConfigurationException("invalid configuration entry: "
>>>>                                             +"renewalDuration ("
>>>>                                             +renewalDuration+") must be "
>>>>                                             +"positive or Lease.ANY");
>>>>        }//endif
>>>> -	this.callback = callback;
>>>>        /* Discovery manager */
>>>> -	if(discMgr == null) {
>>>> +        boolean bCreateDiscMgr = false;
>>>> +	if(discoveryMgr == null) {
>>>> 	    bCreateDiscMgr = true;
>>>>            try {
>>>> -                discMgr = (DiscoveryManagement)config.getEntry
>>>> +                discoveryMgr = (DiscoveryManagement)config.getEntry
>>>>                                                 (COMPONENT_NAME,
>>>>                                                  "discoveryManager",
>>>>                                                  DiscoveryManagement.class);
>>>>            } catch(NoSuchEntryException e) { /* use default */
>>>> -                discMgr = new LookupDiscoveryManager
>>>> +                discoveryMgr = new LookupDiscoveryManager
>>>>                                     (new String[] {""}, null, null, config);
>>>>            }
>>>> 	}//endif
>>>> -	discMgr.addDiscoveryListener(discMgrListener);
>>>> +        return new Conf(registrarPreparer, registrationPreparer, serviceLeasePreparer,
>>>> +                taskMgr, wakeupMgr, maxNRetries, leaseMgr, renewalDuration,
>>>> +                discoveryMgr, bCreateDiscMgr);
>>>> +    }
>>>> +
>>>> +    /** Convenience method invoked by the constructors of this class that
>>>> +     *  uses the given<code>Configuration</code>  to initialize the current
>>>> +     *  instance of this utility, and initiates all join processing for
>>>> +     *  the given parameters. This method handles the various configurations
>>>> +     *  allowed by the different constructors.
>>>> +     */
>>>> +    private JoinManager(Object serviceProxy,
>>>> +                                   Entry[] attrSets, ServiceID serviceID,
>>>> +                                   ServiceIDListener callback, Conf conf)
>>>> +    {
>>>> +	registrarPreparer = conf.registrarPreparer;
>>>> +        registrationPreparer = conf.registrationPreparer;
>>>> +        serviceLeasePreparer = conf.serviceLeasePreparer;
>>>> +        taskMgr = conf.taskManager;
>>>> +        wakeupMgr = conf.wakeupManager;
>>>> +        maxNRetries = conf.maxNretrys;
>>>> +        leaseRenewalMgr = conf.leaseRenewalManager;
>>>> +        renewalDuration = conf.renewalDuration;
>>>> +        bCreateDiscMgr = conf.bcreateDisco;
>>>> +        DiscMgrListener discMgrListen = new DiscMgrListener();
>>>> +        if(attrSets == null) {
>>>> +            lookupAttr = new Entry[0];
>>>> +        } else {
>>>> +            attrSets = attrSets.clone();
>>>> +            LookupAttributes.check(attrSets,false);//null elements NOT ok
>>>> +            lookupAttr = attrSets;
>>>> +        }//endif
>>>> +	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
>>>> +	this.callback = callback;
>>>> +	conf.discoveryMgr.addDiscoveryListener(discMgrListen);
>>>> +        discMgr = conf.discoveryMgr;
>>>> +        discMgrListener = discMgrListen;
>>>>    }//end createJoinManager
>>>>
>>>>    /** For the given lookup service proxy, searches the<code>joinSet</code>
>>>> @@ -2623,9 +2735,10 @@
>>>>                }//end loop
>>>>                /* Interrupt all active tasks, prepare taskMgr for GC. */
>>>>                taskMgr.terminate();
>>>> -                taskMgr = null;
>>>> +        // Too lazy to put out the trash.
>>>> +//                taskMgr = null;
>>>>            }//end sync(taskMgr)
>>>> -            wakeupMgr = null;
>>>> +//            wakeupMgr = null;
>>>>        }//end sync(wakeupMgr)
>>>>    }//end terminateTaskMgr
>>>>
>>>> Index: src/org/apache/river/api/security/URIGrant.java
>>>> --- src/org/apache/river/api/security/URIGrant.java Base (BASE)
>>>> +++ src/org/apache/river/api/security/URIGrant.java Locally Modified (Based On LOCAL)
>>>> @@ -135,12 +135,17 @@
>>>>        if (url == null ) return false;
>>>>        Uri implied = null;
>>>>        try {
>>>> -            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
>>>> -        } catch (PrivilegedActionException ex) {
>>>> -            Exception cause = ex.getException();
>>>> -            cause.printStackTrace(System.err);
>>>> -            return false;
>>>> +            implied = Uri.urlToUri(url);
>>>> +        } catch (URISyntaxException ex) {
>>>> +            Logger.getLogger(URIGrant.class.getName()).log(Level.SEVERE, null, ex);
>>>>        }
>>>> +//        try {
>>>> +//            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
>>>> +//        } catch (PrivilegedActionException ex) {
>>>> +//            Exception cause = ex.getException();
>>>> +//            cause.printStackTrace(System.err);
>>>> +//            return false;
>>>> +//        }
>>>>        for (int i = 0; i<l ; i++){
>>>>            if (uris[i].implies(implied)) return true;
>>>>        }


Re: Indefinite hang - no progress while in loop liveness failure

Posted by Gregg Wonderly <gr...@wonderly.org>.
Okay, I just went back to look again, and I do see a synchronized(this) that I missed.  So that might not be the real issue.  but, at any rate, the computeResult:284 location looks like a mysterious place for the stack trace to reveal.  Typically, threads have to spend a lot of time at a place on the stack, like this, for the thread dump to catch it there.  The largest latency spots are often what you see in these dumps.

Gregg

On Apr 15, 2013, at 10:29 AM, Gregg Wonderly <gr...@wonderly.org> wrote:

> Let me be more specific.  There are many "logic elimination" optimizations in the hit these days.  For non-volatile and unsynchronized access to "class variables", the JIT will make the assessment that because you don't both read and write the variable in the method, that the value will never change, and thus it will read it only once, and do some things such as loop test hoisting.  I haven't had a chance yet to see what code this method generates, but I would almost bet, that something happens in here that eliminates the tests.
> 
> Gregg
> 
> On Apr 14, 2013, at 7:53 PM, Gregg Wonderly <ge...@cox.net> wrote:
> 
>> Because pending is accessed in that method (isCompleted), and it is non-volatile, and the method is not synchronized, all bets are off on predictable behavior.
>> 
>> Gregg Wonderly
>> 
>> On Apr 14, 2013, at 3:16 PM, Peter Firmstone <ji...@zeus.net.au> wrote:
>> 
>>> Gregg,
>>> 
>>> You are so right, I've just spent the weekend trying to fix an unrelated test, fixing one problem reveals another.
>>> 
>>> The patch (attached) attempts to fix some synchronization issues with Mahalo, this patch needs to be applied against qa-refactoring in skunk.
>>> 
>>> These two tests hang indefinitely:
>>> 
>>> com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
>>> 
>>> com.sun.jini.test.impl.mahalo.PrepareAndCommitExceptionTest4.td  (Thread dump for this test appended).
>>> 
>>> 2013-04-15 05:53:48
>>> Full thread dump Java HotSpot(TM) Server VM (20.5-b03 mixed mode):
>>> 
>>> "RMI TCP Connection(332)-10.1.1.2" daemon prio=3 tid=0x007fd800 nid=0x6a runnable [0xb517f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>> at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>>> at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>>> - locked <0xe66ec2e0> (a java.io.BufferedInputStream)
>>> at java.io.FilterInputStream.read(FilterInputStream.java:66)
>>> at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - <0xe645f1d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
>>> 
>>> "(JSK) mux request dispatch" daemon prio=3 tid=0x01013000 nid=0x33 runnable [0xb467d000]
>>> java.lang.Thread.State: RUNNABLE
>>> at com.sun.jini.mahalo.AbortJob.computeResult(AbortJob.java:284)
>>> - locked <0xbb8a2c10> (a com.sun.jini.mahalo.AbortJob)
>>> at com.sun.jini.mahalo.TxnManagerTransaction.abort(TxnManagerTransaction.java:1034)
>>> - locked <0xbb8a2c60> (a java.lang.Object)
>>> at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:795)
>>> at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:754)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>> at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>>> at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>>> at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>>> at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>>> at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>>> at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>>> at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>>> at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>>> at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) mux reader" daemon prio=3 tid=0x01011400 nid=0x32 runnable [0xb477f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) mux reader" daemon prio=3 tid=0x005b0400 nid=0x31 runnable [0xb487f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) mux writer" daemon prio=3 tid=0x005af400 nid=0x30 in Object.wait() [0xb497f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8a6d20> (a java.lang.Object)
>>> at java.lang.Object.wait(Object.java:485)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>> - locked <0xbb8a6d20> (a java.lang.Object)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) mux writer" daemon prio=3 tid=0x005ae000 nid=0x2f in Object.wait() [0xb4a7f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8aad00> (a java.lang.Object)
>>> at java.lang.Object.wait(Object.java:485)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>> - locked <0xbb8aad00> (a java.lang.Object)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) ConnectionManager.Reaper" daemon prio=3 tid=0x007ff000 nid=0x2c waiting on condition [0xb4d7f000]
>>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>> at java.lang.Thread.sleep(Native Method)
>>> at net.jini.jeri.connection.ConnectionManager$Reaper.run(ConnectionManager.java:597)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) mux request dispatch" daemon prio=3 tid=0x006a0800 nid=0x2a in Object.wait() [0xb4f7d000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8aaf10> (a java.lang.Object)
>>> at java.lang.Object.wait(Object.java:485)
>>> at com.sun.jini.jeri.internal.mux.Session$MuxInputStream.read(Session.java:853)
>>> - locked <0xbb8aaf10> (a java.lang.Object)
>>> at net.jini.jeri.connection.ConnectionManager$Outbound$Input.read(ConnectionManager.java:550)
>>> at net.jini.jeri.BasicObjectEndpoint.executeCall(BasicObjectEndpoint.java:410)
>>> at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:806)
>>> at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
>>> at net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
>>> at $Proxy0.abort(Unknown Source)
>>> at com.sun.jini.mahalo.TxnMgrProxy.abort(TxnMgrProxy.java:146)
>>> at net.jini.core.transaction.server.ServerTransaction.abort(ServerTransaction.java:113)
>>> at com.sun.jini.mahalo.TxnManagerTransaction.doAbort(TxnManagerTransaction.java:1134)
>>> at com.sun.jini.mahalo.TxnManagerTransaction.commit(TxnManagerTransaction.java:763)
>>> at com.sun.jini.mahalo.TxnManagerImpl.commit(TxnManagerImpl.java:712)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>> at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>>> at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>>> at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>>> at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>>> at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>>> at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>>> at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>>> at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>>> at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>>> at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>>> at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) mux reader" daemon prio=3 tid=0x003bfc00 nid=0x26 runnable [0xb537f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) mux writer" daemon prio=3 tid=0x00984400 nid=0x25 in Object.wait() [0xb547f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8bad70> (a java.lang.Object)
>>> at java.lang.Object.wait(Object.java:485)
>>> at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>> - locked <0xbb8bad70> (a java.lang.Object)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "event listener notification" daemon prio=3 tid=0x00483000 nid=0x23 in Object.wait() [0xb567f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8bb778> (a java.util.LinkedList)
>>> at java.lang.Object.wait(Object.java:485)
>>> at net.jini.discovery.LookupDiscovery$Notifier.run(LookupDiscovery.java:920)
>>> - locked <0xbb8bb778> (a java.util.LinkedList)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "multicast announcement timer" daemon prio=3 tid=0x00ade000 nid=0x22 waiting on condition [0xb577f000]
>>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>> at java.lang.Thread.sleep(Native Method)
>>> at net.jini.discovery.LookupDiscovery$AnnouncementTimerThread.run(LookupDiscovery.java:1434)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "multicast discovery announcement listener" daemon prio=3 tid=0x00adcc00 nid=0x21 runnable [0xb587f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.PlainDatagramSocketImpl.peekData(Native Method)
>>> - locked <0xbb8bdab8> (a java.net.PlainDatagramSocketImpl)
>>> at java.net.DatagramSocket.receive(DatagramSocket.java:675)
>>> - locked <0xbb8bfae8> (a java.net.DatagramPacket)
>>> - locked <0xbb8bda80> (a java.net.MulticastSocket)
>>> at net.jini.discovery.LookupDiscovery$AnnouncementListener.run(LookupDiscovery.java:1205)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "settleThread" daemon prio=3 tid=0x00669c00 nid=0x1e in Object.wait() [0xb5b7f000]
>>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
>>> at com.sun.jini.mahalo.TxnManagerImpl.settleTxns(TxnManagerImpl.java:885)
>>> - locked <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
>>> at com.sun.jini.mahalo.TxnManagerImpl.access$100(TxnManagerImpl.java:117)
>>> at com.sun.jini.mahalo.TxnManagerImpl$2.run(TxnManagerImpl.java:331)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) KeepAlive" prio=3 tid=0x005cc800 nid=0x1d waiting on condition [0xb5c7f000]
>>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>> at java.lang.Thread.sleep(Native Method)
>>> at com.sun.jini.jeri.internal.runtime.JvmLifeSupport$2.run(JvmLifeSupport.java:133)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) Reaper" daemon prio=3 tid=0x005cc000 nid=0x1c in Object.wait() [0xb5d7f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>> - locked <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>> at com.sun.jini.jeri.internal.runtime.ImplRefManager$Reaper.run(ImplRefManager.java:426)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "(JSK) TcpServerEndpoint.LH[ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=36713]] accept loop" daemon prio=3 tid=0x005ce400 nid=0x1b runnable [0xb5e7f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.PlainSocketImpl.socketAccept(Native Method)
>>> at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>> - locked <0xbb8b8708> (a java.net.SocksSocketImpl)
>>> at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>> at java.net.ServerSocket.accept(ServerSocket.java:430)
>>> at net.jini.jeri.tcp.TcpServerEndpoint$LH.executeAcceptLoop(TcpServerEndpoint.java:797)
>>> at net.jini.jeri.tcp.TcpServerEndpoint$LH.access$400(TcpServerEndpoint.java:735)
>>> at net.jini.jeri.tcp.TcpServerEndpoint$LH$1.run(TcpServerEndpoint.java:767)
>>> at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>> at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "RMI TCP Connection(331)-10.1.1.2" daemon prio=3 tid=0x003a8c00 nid=0x1a runnable [0xb5f7f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.SocketInputStream.socketRead0(Native Method)
>>> at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>> at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>>> at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>>> - locked <0xe66b5280> (a java.io.BufferedInputStream)
>>> at java.io.FilterInputStream.read(FilterInputStream.java:66)
>>> at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>>> at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - <0xbb8c0420> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
>>> 
>>> "JMX server connection timeout 18" daemon prio=3 tid=0x005cf800 nid=0x19 in Object.wait() [0xb607f000]
>>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8c0718> (a [I)
>>> at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150)
>>> - locked <0xbb8c0718> (a [I)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "RMI Scheduler(0)" daemon prio=3 tid=0x005d1400 nid=0x18 waiting on condition [0xb617f000]
>>> java.lang.Thread.State: TIMED_WAITING (parking)
>>> at sun.misc.Unsafe.park(Native Method)
>>> - parking to wait for  <0xbb8a2178> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>>> at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>>> at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>>> at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>>> at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "DestroyJavaVM" prio=3 tid=0x00031800 nid=0x2 waiting on condition [0x00000000]
>>> java.lang.Thread.State: RUNNABLE
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "Thread-1" prio=3 tid=0x004be800 nid=0x17 runnable [0xb627f000]
>>> java.lang.Thread.State: TIMED_WAITING (parking)
>>> at sun.misc.Unsafe.park(Native Method)
>>> - parking to wait for  <0xbb8c0cd0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>>> at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>>> at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>>> at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>>> at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>>> at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>>> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "GC Daemon" daemon prio=3 tid=0x0052dc00 nid=0x15 in Object.wait() [0xb647f000]
>>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb8076b8> (a sun.misc.GC$LatencyLock)
>>> at sun.misc.GC$Daemon.run(GC.java:100)
>>> - locked <0xbb8076b8> (a sun.misc.GC$LatencyLock)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "RMI Reaper" prio=3 tid=0x00529800 nid=0x14 in Object.wait() [0xb657f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>> - locked <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>> at sun.rmi.transport.ObjectTable$Reaper.run(ObjectTable.java:333)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "RMI TCP Accept-0" daemon prio=3 tid=0x002f5400 nid=0x13 runnable [0xb667f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.PlainSocketImpl.socketAccept(Native Method)
>>> at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>> - locked <0xbb8001a8> (a java.net.SocksSocketImpl)
>>> at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>> at java.net.ServerSocket.accept(ServerSocket.java:430)
>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "RMI TCP Accept-0" daemon prio=3 tid=0x002f4c00 nid=0x12 runnable [0xb677f000]
>>> java.lang.Thread.State: RUNNABLE
>>> at java.net.PlainSocketImpl.socketAccept(Native Method)
>>> at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>> - locked <0xbb803c98> (a java.net.SocksSocketImpl)
>>> at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>> at java.net.ServerSocket.accept(ServerSocket.java:430)
>>> at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:34)
>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>>> at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>>> at java.lang.Thread.run(Thread.java:662)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "Attach Listener" daemon prio=3 tid=0x0020ac00 nid=0xf waiting on condition [0x00000000]
>>> java.lang.Thread.State: RUNNABLE
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "Low Memory Detector" daemon prio=3 tid=0x00124000 nid=0xd runnable [0x00000000]
>>> java.lang.Thread.State: RUNNABLE
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "C2 CompilerThread1" daemon prio=3 tid=0x00121000 nid=0xc waiting on condition [0x00000000]
>>> java.lang.Thread.State: RUNNABLE
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "C2 CompilerThread0" daemon prio=3 tid=0x0011ec00 nid=0xb waiting on condition [0x00000000]
>>> java.lang.Thread.State: RUNNABLE
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "Signal Dispatcher" daemon prio=3 tid=0x0011d000 nid=0xa runnable [0x00000000]
>>> java.lang.Thread.State: RUNNABLE
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "Finalizer" daemon prio=3 tid=0x0010c800 nid=0x9 in Object.wait() [0xb707f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>> - locked <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
>>> at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>> at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "Reference Handler" daemon prio=3 tid=0x00107c00 nid=0x8 in Object.wait() [0xb717f000]
>>> java.lang.Thread.State: WAITING (on object monitor)
>>> at java.lang.Object.wait(Native Method)
>>> - waiting on <0xbb804090> (a java.lang.ref.Reference$Lock)
>>> at java.lang.Object.wait(Object.java:485)
>>> at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
>>> - locked <0xbb804090> (a java.lang.ref.Reference$Lock)
>>> 
>>> Locked ownable synchronizers:
>>> - None
>>> 
>>> "VM Thread" prio=3 tid=0x00104000 nid=0x7 runnable
>>> 
>>> "GC task thread#0 (ParallelGC)" prio=3 tid=0x00039000 nid=0x3 runnable
>>> 
>>> "GC task thread#1 (ParallelGC)" prio=3 tid=0x0003a800 nid=0x4 runnable
>>> 
>>> "GC task thread#2 (ParallelGC)" prio=3 tid=0x0003bc00 nid=0x5 runnable
>>> 
>>> "GC task thread#3 (ParallelGC)" prio=3 tid=0x0003d000 nid=0x6 runnable
>>> 
>>> "VM Periodic Task Thread" prio=3 tid=0x00136000 nid=0xe waiting on condition
>>> 
>>> JNI global references: 1404
>>> 
>>> # This patch file was generated by NetBeans IDE
>>> # Following Index: paths are relative to: /opt/src/River_Fixed/peterConcurrentPolicy
>>> # This patch can be applied using context Tools: Patch action on respective folder.
>>> # It uses platform neutral UTF-8 encoding and \n newlines.
>>> # Above lines and this line are ignored by the patching process.
>>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td
>>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Base (BASE)
>>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Locally Modified (Based On LOCAL)
>>> @@ -1,3 +1,6 @@
>>> include0=mahalo.properties
>>> testClass=PrepareAndCommitExceptionTest
>>> testCategories=txnmanager,txnmanager_impl
>>> +#testjvmargs=-Xdebug,\
>>> +#-Xrunjdwp:transport=dt_socket+,address=8000+,server=y+,suspend=y,\
>>> +#${testjvmargs}
>>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java
>>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Base (BASE)
>>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Locally Modified (Based On LOCAL)
>>> @@ -44,15 +44,15 @@
>>> */
>>> public class PrepareAndCommitExceptionTest2 extends TxnManagerTest {
>>> 
>>> -      class Clearer implements Runnable {
>>> -         TestParticipant part;
>>> +      static class Clearer implements Runnable {
>>> +         final TestParticipant part;
>>>        Clearer(TestParticipant part) {
>>>            this.part = part;
>>>        }
>>> 
>>>        public void run() {
>>>           try {
>>> -                Thread.sleep(10000);
>>> +                Thread.sleep(1000); // was 10 minutes, not necessary on modern hardware.
>>>           } catch (Exception e) {
>>>               logger.log(Level.INFO, "Caught sleep exception -- ignoring: " + e);                                    
>>>           }
>>> @@ -94,7 +94,7 @@
>>>       t.start();
>>>       logger.log(Level.INFO, "Committing transaction");                        
>>>       try {
>>> -            cr.transaction.commit(60000);
>>> +            cr.transaction.commit(2000); // Was 60 minutes, didn't feel like waiting that long!
>>>           throw new TestException("ServerException not thrown");
>>>       } catch (ServerException se) {
>>>           logger.log(Level.INFO, "Caught expected exception: " + se);                                    
>>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
>>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Base (BASE)
>>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Locally Modified (Based On LOCAL)
>>> @@ -1,3 +1,4 @@
>>> include0=mahalo.properties
>>> testClass=PrepareAndCommitExceptionTest2
>>> testCategories=txnmanager,txnmanager_impl
>>> +# This test presently hangs, if the Clearer thread runs after the commit timeout, it doesn't occur.
>>> \ No newline at end of file
>>> Index: qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java
>>> --- qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Base (BASE)
>>> +++ qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Locally Modified (Based On LOCAL)
>>> @@ -68,11 +68,11 @@
>>>   private long sleep_time = SLEEP_TIME;
>>> 
>>>   // Another values.
>>> -    private TransactionManager mgr = null;
>>> +    private volatile TransactionManager mgr = null;
>>>   private TaskManager threadpool = null;
>>> -    private WakeupManager wakeupManager = null;
>>> -    private Random random;
>>> -    private long seed = 0;
>>> +    private volatile WakeupManager wakeupManager = null;
>>> +    private volatile Random random;
>>> +    private volatile long seed = 0;
>>> 
>>>   public Test construct(QAConfig sysConfig) throws Exception {
>>>       super.construct(sysConfig);
>>> Index: qa/src/com/sun/jini/test/share/TestParticipantImpl.java
>>> --- qa/src/com/sun/jini/test/share/TestParticipantImpl.java Base (BASE)
>>> +++ qa/src/com/sun/jini/test/share/TestParticipantImpl.java Locally Modified (Based On LOCAL)
>>> @@ -19,6 +19,8 @@
>>> package com.sun.jini.test.share;
>>> 
>>> import com.sun.jini.mahalo.*;
>>> +import java.util.logging.Level;
>>> +import java.util.logging.Logger;
>>> import net.jini.core.transaction.*;
>>> import net.jini.core.transaction.server.*;
>>> 
>>> @@ -48,15 +50,16 @@
>>> 	       TransactionParticipant, TestParticipant, ProxyAccessor,
>>> 	       ServerProxyTrust
>>> {
>>> -    private String name;
>>> -    private BitSet behavior; 
>>> +    private final String name;
>>> +    private final BitSet behavior; 
>>>   private final Object lock2;
>>> -    private long crashcount;
>>> -    private ServerTransaction str;
>>> +    private volatile long crashcount; // atomic increment with lock2
>>> +    private volatile ServerTransaction str;
>>>   private static final long TENSECONDS = 1000 * 10;
>>>   private static final long THIRTYSECONDS = TENSECONDS *3;
>>>   private static final boolean DEBUG = true;
>>> -    private TransactionParticipant proxy;
>>> +    private volatile TransactionParticipant proxy = null;
>>> +    private Exporter exporter;
>>> 
>>>   public TestParticipantImpl() throws RemoteException {
>>> 	this(DEFAULT_NAME);
>>> @@ -68,7 +71,7 @@
>>> 	crashcount = System.currentTimeMillis();
>>> 	behavior   = new BitSet(OPERATION_COUNT);
>>> 	Configuration c = QAConfig.getConfig().getConfiguration();
>>> -	Exporter exporter = QAConfig.getDefaultExporter();
>>> +	exporter = QAConfig.getDefaultExporter();
>>> 	if (c instanceof com.sun.jini.qa.harness.QAConfiguration) {
>>> 	    try {
>>> 		exporter = (Exporter) c.getEntry("test",
>>> @@ -78,15 +81,28 @@
>>> 		throw new RemoteException("Configuration Error", e);
>>> 	    }
>>> 	}
>>> -	proxy = (TransactionParticipant)exporter.export(this);
>>> +        // Can't export here without this escaping.
>>>   }
>>> 
>>>   public Object getProxy() {
>>> +        if (proxy != null){
>>> 	return proxy;
>>> +        } else {
>>> +            synchronized (lock2){
>>> +                if (proxy != null) return proxy; // Don't export it twice.
>>> +                try {
>>> +                    proxy = (TransactionParticipant)exporter.export(this);
>>> +                    exporter = null;
>>> +                } catch (ExportException ex) {
>>> +                    // Nothing we can do
>>>   }
>>> +            }
>>> +        }
>>> +        return proxy; // May be null
>>> +    }
>>> 
>>>   public TrustVerifier getProxyVerifier() {
>>> -	return new BasicProxyTrustVerifier(proxy);
>>> +	return new BasicProxyTrustVerifier(getProxy());
>>>   }
>>> 
>>>   private boolean checkBit(int bit) {
>>> @@ -136,7 +152,7 @@
>>> 		System.out.println(name + ": joining");
>>> 	    }
>>> 
>>> -	    str.join(proxy, crashcount);
>>> +	    str.join((TransactionParticipant) getProxy(), crashcount);
>>> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
>>> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
>>> 		    doTimeout(THIRTYSECONDS);
>>> @@ -157,7 +173,7 @@
>>> 		System.out.println(name + ": joining again");
>>> 	    }
>>> 
>>> -	    str.join(proxy, crashcount);
>>> +	    str.join((TransactionParticipant) getProxy(), crashcount);
>>> 
>>> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
>>> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
>>> Index: qa/src/com/sun/jini/test/share/TxnManagerTest.java
>>> --- qa/src/com/sun/jini/test/share/TxnManagerTest.java Base (BASE)
>>> +++ qa/src/com/sun/jini/test/share/TxnManagerTest.java Locally Modified (Based On LOCAL)
>>> @@ -42,16 +42,20 @@
>>> {
>>>   protected static final boolean DEBUG = true;
>>> 
>>> -    TransactionManager[] mgrs = new TransactionManager[1];
>>> +    final TransactionManager[] mgrs = new TransactionManager[1];
>>> 
>>>   public TransactionManager manager() throws RemoteException {
>>> +        synchronized (mgrs){
>>> 	return (TransactionManager) mgrs[0];
>>>   }
>>> +    }
>>> 
>>>   protected void startTxnMgr() throws TestException {
>>> 	specifyServices(new Class[] {TransactionManager.class}); 
>>> +        synchronized (mgrs){
>>> 	mgrs[0]= (TransactionManager)services[0]; // prepared by specifyServices
>>>   }
>>> +    }
>>> 
>>>   public Test construct(QAConfig config) throws Exception {
>>>       super.construct(config);
>>> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java
>>> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Base (BASE)
>>> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Locally Modified (Based On LOCAL)
>>> @@ -192,7 +192,9 @@
>>>           if (trc == null) {
>>>               throw new TestException("Null transaction has been obtained.");
>>>           }
>>> +            synchronized (txns){
>>>           txns.add(trc.transaction);
>>> +            }
>>>           return trc.transaction;
>>>       } catch (Exception e) {
>>>           throw new TestException("Could not create transaction.", e);
>>> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties
>>> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Base (BASE)
>>> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Locally Modified (Based On LOCAL)
>>> @@ -15,8 +15,8 @@
>>> 
>>> # timeout2 must be greater than (timeout1 + instantTime)
>>> # it is recommended that timeout2 be greater than (timeout1 + 2*instantTime)
>>> -com.sun.jini.test.spec.javaspace.conformance.timeout1=24000
>>> -com.sun.jini.test.spec.javaspace.conformance.timeout2=48000
>>> +com.sun.jini.test.spec.javaspace.conformance.timeout1=20000
>>> +com.sun.jini.test.spec.javaspace.conformance.timeout2=40000
>>> 
>>> #  general round trip time expected to non-blocking operations.
>>> #  should be set to checkTime / 2. 
>>> Index: qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java
>>> --- qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Base (BASE)
>>> +++ qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Locally Modified (Based On LOCAL)
>>> @@ -80,11 +80,11 @@
>>>           while (true) {
>>>               state = str.mgr.getState(str.id);
>>> 
>>> -                if (DEBUG) {
>>> -                    int st = state;
>>> -                    logger.log(Level.INFO, "state = "
>>> -                            + com.sun.jini.constants.TxnConstants.getName(st));
>>> -                }
>>> +//                if (DEBUG) {
>>> +//                    int st = state;
>>> +//                    logger.log(Level.FINEST, "state = "
>>> +//                            + com.sun.jini.constants.TxnConstants.getName(st));
>>> +//                }
>>> 
>>>               if (state == COMMITTED) {
>>>                   break;
>>> Index: qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java
>>> --- qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Base (BASE)
>>> +++ qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Locally Modified (Based On LOCAL)
>>> @@ -21,15 +21,16 @@
>>> 
>>> 
>>> class CommitThread extends Thread {
>>> -    long timeOut;
>>> -    Transaction tr;
>>> +    final long timeOut;
>>> +    final Transaction tr;
>>> 
>>>   public CommitThread(Transaction tr) {
>>>       this.tr = tr;
>>> +        timeOut = 0;
>>>   }
>>> 
>>>   public CommitThread(Transaction tr, long timeOut) {
>>> -        this(tr);
>>> +        this.tr = tr;
>>> 
>>>       if (timeOut < 0) {
>>>           throw new IllegalArgumentException("timeout must be non-negative");
>>> Index: src/com/sun/jini/collection/WeakTable.java
>>> --- src/com/sun/jini/collection/WeakTable.java Base (BASE)
>>> +++ src/com/sun/jini/collection/WeakTable.java Locally Modified (Based On LOCAL)
>>> @@ -52,16 +52,16 @@
>>> */
>>> public class WeakTable {
>>>   /** The map of known objects.  */
>>> -    private HashMap		table = new HashMap();
>>> +    private final HashMap table;
>>> 
>>>   /** The queue of cleared SpaceProxy objects. */
>>> -    private ReferenceQueue	refQueue = new ReferenceQueue();
>>> +    private final ReferenceQueue refQueue;
>>> 
>>>   /** Print debug messages to this stream if not <code>null</code>. */
>>>   private static PrintStream		DEBUG = null;
>>> 
>>>   /** Object to call back when keys are collected */
>>> -    private KeyGCHandler handler = null;
>>> +    private final KeyGCHandler handler;
>>> 
>>>   /**
>>>    * Create a new WeakTable object to maintain the maps.
>>> @@ -72,6 +72,7 @@
>>> 
>>> 	table = new HashMap();
>>> 	refQueue = new ReferenceQueue();
>>> +        handler = null;
>>>   }
>>> 
>>>   /**
>>> @@ -79,7 +80,11 @@
>>>    * back the designated object when keys are collected.
>>>    */
>>>   public WeakTable(KeyGCHandler handler) {
>>> -	this();
>>> +        if (DEBUG != null)
>>> +	    DEBUG.println("Creating WeakTable");
>>> +
>>> +	table = new HashMap();
>>> +	refQueue = new ReferenceQueue();
>>> 	this.handler = handler;
>>>   }
>>> 
>>> Index: src/com/sun/jini/mahalo/AbortJob.java
>>> --- src/com/sun/jini/mahalo/AbortJob.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/AbortJob.java Locally Modified (Based On LOCAL)
>>> @@ -29,6 +29,7 @@
>>> import java.rmi.ConnectIOException;
>>> import java.rmi.AccessException;
>>> import java.rmi.ConnectException;
>>> +import java.util.Iterator;
>>> 
>>> import java.util.logging.Level;
>>> import java.util.logging.Logger;
>>> @@ -54,10 +55,10 @@
>>> *
>>> */
>>> public class AbortJob extends Job implements TransactionConstants {
>>> -    ServerTransaction tr;
>>> -    ClientLog log;
>>> -    ParticipantHandle[] handles;
>>> -    int maxtries = 5;
>>> +    final ServerTransaction tr;
>>> +    final ClientLog log;
>>> +    final ParticipantHandle[] handles;
>>> +    final int maxtries = 5;
>>>   static final Logger logger = TxnManagerImpl.participantLogger;
>>> 
>>>   /**
>>> @@ -272,13 +273,16 @@
>>> 	int tmp = 0;
>>> 	int count = 0;
>>> 
>>> -	checkresults:
>>> -	for (int i = 0; i < results.length; i++) {
>>> -	    tmp = ((Integer)results[i]).intValue();
>>> -
>>> -	    if (tmp == ABORTED)
>>> -		count++;
>>> +        synchronized (this){
>>> +            Iterator i = results.values().iterator();
>>> +            while (i.hasNext()){
>>> +                Object res = i.hasNext();
>>> +                if (res instanceof Integer){
>>> +                    tmp = ((Integer)res).intValue();
>>> +                    if (tmp == ABORTED) count++;
>>> 	}
>>> +            }
>>> +        }
>>> 
>>>       if (logger.isLoggable(Level.FINEST)) {
>>>           logger.log(Level.FINEST,
>>> Index: src/com/sun/jini/mahalo/AbortRecord.java
>>> --- src/com/sun/jini/mahalo/AbortRecord.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/AbortRecord.java Locally Modified (Based On LOCAL)
>>> @@ -33,7 +33,7 @@
>>>   /**
>>>    * @serial
>>>    */
>>> -    private ParticipantHandle[] parts;
>>> +    private final ParticipantHandle[] parts;
>>> 
>>>   static final long serialVersionUID = -8121722031382234695L;
>>> 
>>> Index: src/com/sun/jini/mahalo/CommitJob.java
>>> --- src/com/sun/jini/mahalo/CommitJob.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/CommitJob.java Locally Modified (Based On LOCAL)
>>> @@ -29,6 +29,7 @@
>>> import java.rmi.ConnectIOException;
>>> import java.rmi.AccessException;
>>> import java.rmi.ConnectException;
>>> +import java.util.Iterator;
>>> 
>>> import java.util.logging.Level;
>>> import java.util.logging.Logger;
>>> @@ -51,10 +52,10 @@
>>> * @see net.jini.core.transaction.server.TransactionParticipant
>>> */
>>> public class CommitJob extends Job implements TransactionConstants {
>>> -    ServerTransaction tr;
>>> -    ClientLog log;
>>> -    ParticipantHandle[] handles;
>>> -    int maxtries = Integer.MAX_VALUE;
>>> +    final ServerTransaction tr;
>>> +    final ClientLog log;
>>> +    final ParticipantHandle[] handles;
>>> +    final int maxtries = Integer.MAX_VALUE;
>>>   static final Logger logger = TxnManagerImpl.participantLogger;
>>> 
>>>   /**
>>> @@ -266,13 +267,13 @@
>>> 	int tmp = 0;
>>> 	int count = 0;
>>> 
>>> -	checkresults:
>>> -	for (int i = 0; i < results.length; i++) {
>>> -	    tmp = ((Integer)results[i]).intValue();
>>> -
>>> -	    if (tmp == COMMITTED)
>>> -		count++;
>>> +        synchronized (this){
>>> +            Iterator i = results.values().iterator();
>>> +            while (i.hasNext()){
>>> +                tmp = ((Integer)i.next()).intValue();
>>> +                if (tmp == COMMITTED) count++;
>>> 	}
>>> +        }
>>> 
>>>       if (logger.isLoggable(Level.FINEST)) {
>>>           logger.log(Level.FINEST,
>>> Index: src/com/sun/jini/mahalo/CommitRecord.java
>>> --- src/com/sun/jini/mahalo/CommitRecord.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/CommitRecord.java Locally Modified (Based On LOCAL)
>>> @@ -39,7 +39,7 @@
>>>   /**
>>>    * @serial
>>>    */
>>> -    ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
>>> +    final ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
>>> 			       //      We want a list of things.  By using
>>> 			       //      an array, we can use the type system
>>> 			       //      to guarantee that each thing is a
>>> Index: src/com/sun/jini/mahalo/Job.java
>>> --- src/com/sun/jini/mahalo/Job.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/Job.java Locally Modified (Based On LOCAL)
>>> @@ -19,9 +19,13 @@
>>> 
>>> import com.sun.jini.thread.TaskManager;
>>> import com.sun.jini.thread.WakeupManager;
>>> +import java.util.ArrayList;
>>> import java.util.HashMap;
>>> +import java.util.List;
>>> import java.util.Map;
>>> import java.util.Set;
>>> +import java.util.concurrent.ConcurrentHashMap;
>>> +import java.util.concurrent.atomic.AtomicIntegerArray;
>>> import java.util.logging.Level;
>>> import java.util.logging.Logger;
>>> 
>>> @@ -34,14 +38,15 @@
>>> *
>>> */
>>> public abstract class Job {
>>> -    private TaskManager pool;
>>> -    private WakeupManager wm;
>>> -    private int pending = -1;
>>> -    Object[] results;
>>> -    int[] attempts;
>>> -    private Map tasks = new HashMap();  //used to maintain account
>>> +    private final TaskManager pool;
>>> +    private final WakeupManager wm;
>>> +    private int pending = -1; // Synchronized on this.
>>> +    final Map<Integer,Object> results = new HashMap<Integer,Object>(); // sync on this.
>>> +    volatile AtomicIntegerArray attempts; // reference changed while synchronized on this
>>> +    private final Map<Object,Integer> tasks = new HashMap<Object,Integer>();  //used to maintain account
>>> 					//of the tasks for which
>>> 					//the job is responsible
>>> +                                        // sync on tasks.
>>> 
>>>   static final Logger logger = TxnManagerImpl.participantLogger;
>>> 
>>> @@ -75,23 +80,31 @@
>>> 	}
>>> 
>>> 	if (tmp == null)
>>> -	    throw new UnknownTaskException();
>>> +	    throw new UnknownTaskException("Task didn't belong to this job");
>>> 
>>> 	int rank = tmp.intValue();
>>> 
>>> -	synchronized (attempts) {
>>> -	    attempts[rank]++;
>>> -	}
>>> +//	synchronized (attempts) {
>>> +//	    attempts[rank]++;
>>> +//	}
>>> 
>>> -	Object result = doWork(who, param);
>>> -	if (result == null)
>>> +        attempts.incrementAndGet(rank);
>>> +
>>> +	Object r = doWork(who, param);
>>> +	if (r == null)
>>> 	    return false;
>>> 
>>> 	try {
>>> -	    reportDone(who, result);
>>> +	    reportDone(who, r);
>>> 	} catch (UnknownTaskException e) {
>>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>>> +            e.printStackTrace(System.err);
>>> 	} catch (PartialResultException e) {
>>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>>> +            e.printStackTrace(System.err);
>>> 	} catch (JobException e) {
>>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>>> +            e.printStackTrace(System.err);
>>> 	}
>>> 
>>> 	return true;
>>> @@ -112,15 +125,14 @@
>>> 	    tmp = (Integer)tasks.get(who);
>>> 	}
>>> 
>>> -	if (tmp == null)
>>> -	    throw new UnknownTaskException();
>>> +	if (tmp == null) throw new UnknownTaskException();
>>> 
>>> 	int rank = tmp.intValue();
>>> -
>>> -	synchronized(attempts)  {
>>> -	    return attempts[rank];
>>> +//	synchronized(attempts)  {
>>> +//	    return attempts[rank];
>>> +//	}
>>> +        return attempts.get(rank);
>>> 	}
>>> -    }
>>> 
>>> 
>>> 
>>> @@ -150,37 +162,39 @@
>>>    */
>>>   public void scheduleTasks() {
>>> 	TaskManager.Task[] tmp = createTasks();
>>> -
>>> +        int length = tmp.length;
>>> 	if (tmp != null) {
>>>           if (logger.isLoggable(Level.FINEST)) {
>>>               logger.log(Level.FINEST,
>>>                   "Job:scheduleTasks with {0} tasks",
>>> -                    Integer.valueOf(tmp.length));
>>> +                    Integer.valueOf(length));
>>>           }
>>> 
>>> -	    results = new Object[tmp.length];
>>> -	    attempts = new int[tmp.length];
>>> -	    setPending(tmp.length);
>>> +            synchronized (this){ 
>>> +                results.clear();
>>> +                attempts = new AtomicIntegerArray(length);
>>> +                setPending(length);
>>> +            }
>>> +            for (int i = 0; i < length; i++) {
>>> 
>>> -	    for (int i = 0; i < tmp.length; i++) {
>>> -
>>> 		//Record the position if each
>>> 		//task for later use when assembling
>>> 		//the partial results
>>> 
>>> 		synchronized(tasks) {
>>> 		    tasks.put(tmp[i],Integer.valueOf(i));
>>> +                }
>>> 		    pool.add(tmp[i]);
>>>                   if (logger.isLoggable(Level.FINEST)) {
>>>                       logger.log(Level.FINEST,
>>>                           "Job:scheduleTasks added {0} to thread pool",
>>>                           tmp[i]);
>>>                   }
>>> -		    attempts[i] = 0;
>>> +                attempts.set(i,0);
>>> 		}
>>> +            
>>> 	    }
>>> 	}
>>> -    }
>>> 
>>> 
>>>   private synchronized void awaitPending(long waitFor) {
>>> @@ -289,19 +303,21 @@
>>> 	if (position == null) 
>>> 	    throw new UnknownTaskException();
>>> 
>>> -	synchronized(results) {
>>> -	    if (results[position.intValue()] == null) {
>>> +        synchronized (this){
>>> +            Object exists = results.get(position);
>>> +            if (exists == null){
>>>               if (logger.isLoggable(Level.FINEST)) {
>>>                   logger.log(Level.FINEST,
>>>                       "Job:reportDone who = {0}, param = {1}",
>>> 		        new Object[] { who, param});
>>>               }
>>> -	        results[position.intValue()] = param;
>>> +                results.put(position, param);
>>> 	        decrementPending();
>>> 	    } else {
>>> 	        throw new PartialResultException("result already set");
>>> 	    }
>>> 	}
>>> +        
>>>   }
>>> 
>>> 
>>> @@ -347,21 +363,25 @@
>>>    * the <code>Job</code>
>>>    */
>>>   public void stop() {
>>> +        Object[] vals;
>>> +        synchronized (tasks){
>>> 	Set s = tasks.keySet();
>>> -	Object[] vals = s.toArray();
>>> +            vals = s.toArray();
>>> +            tasks.clear();
>>> +        }
>>> 
>>> 	//Remove and interrupt all tasks
>>> -
>>> -	for (int i = 0; i < vals.length; i++) {
>>> +        int l = vals.length;
>>> +	for (int i = 0; i < l; i++) {
>>> 	    TaskManager.Task t = (TaskManager.Task) vals[i];
>>> 	    pool.remove(t);
>>> 	}
>>> 
>>> 	//Erase record of tasks, results and the
>>> 	//counting mechanism
>>> -
>>> -	tasks = new HashMap();
>>> +        synchronized (this){
>>> 	setPending(-1);
>>> -	results = null;
>>> +            results.clear();
>>>   }
>>> }
>>> +}
>>> Index: src/com/sun/jini/mahalo/JoinStateManager.java
>>> --- src/com/sun/jini/mahalo/JoinStateManager.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/JoinStateManager.java Locally Modified (Based On LOCAL)
>>> @@ -74,41 +74,41 @@
>>>   private static final Logger persistenceLogger = TxnManagerImpl.persistenceLogger;
>>> 
>>>   /** <code>ProxyPreparer</code> for <code>LookupLocators</code> */
>>> -    private ProxyPreparer lookupLocatorPreparer;
>>> +    private volatile ProxyPreparer lookupLocatorPreparer;
>>> 
>>>   /**
>>>    * Object used to find lookups. Has to implement DiscoveryManagement
>>>    * and DiscoveryLocatorManagement as well as DiscoveryGroupManagement.
>>>    */
>>> -    private DiscoveryManagement dm;
>>> +    private volatile DiscoveryManagement dm;
>>> 
>>>   /**
>>>    * <code>JoinManager</code> that is handling the details of binding
>>>    * into Jini lookup services.
>>>    */
>>> -    private JoinManager  mgr;
>>> +    private volatile JoinManager  mgr;
>>> 
>>>   /**
>>>    * The object coordinating our persistent state.
>>>    */
>>> -    private ReliableLog log;
>>> +    private volatile ReliableLog log;
>>> 
>>>   /**
>>>    * The join state, this data needs to be persisted between restarts
>>>    */
>>> -    private Entry[]		attributes;
>>> -    private LookupLocator[]	locators;
>>> -    private String[]		groups;
>>> +    private volatile Entry[]		attributes;
>>> +    private volatile LookupLocator[]	locators;
>>> +    private volatile String[]		groups;
>>> 
>>>   /** Service's internal <code>Uuid</code> which needs to be persisted */
>>> -    private Uuid		serviceUuid;
>>> +    private volatile Uuid		serviceUuid;
>>> 
>>>   /**
>>>    * Conceptually, true if this is the first time this
>>>    * service has come up, implemented as if there was
>>>    * no previous state then this is the first time.
>>>    */
>>> -    private boolean initial = true;
>>> +    private volatile boolean initial = true;
>>> 
>>>   /**
>>>    * Simple constructor.
>>> Index: src/com/sun/jini/mahalo/LeaseExpirationMgr.java
>>> --- src/com/sun/jini/mahalo/LeaseExpirationMgr.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/LeaseExpirationMgr.java Locally Modified (Based On LOCAL)
>>> @@ -57,9 +57,9 @@
>>> 
>>> 
>>>   // Map of resources to tickets
>>> -    private WeakTable		ticketMap = new WeakTable(this); 
>>> -    private Expirer		landlord;
>>> -    private WakeupManager expirationQueue
>>> +    private final WeakTable		ticketMap = new WeakTable(this); 
>>> +    private final Expirer		landlord;
>>> +    private final WakeupManager expirationQueue
>>>       = new WakeupManager(new WakeupManager.ThreadDesc(null, true));
>>> 
>>>   /**
>>> Index: src/com/sun/jini/mahalo/ParticipantHandle.java
>>> --- src/com/sun/jini/mahalo/ParticipantHandle.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/ParticipantHandle.java Locally Modified (Based On LOCAL)
>>> @@ -38,17 +38,17 @@
>>>   /**
>>>    * Cached reference to prepared participant.
>>>    */
>>> -    private transient TransactionParticipant preparedPart;
>>> +    private volatile transient TransactionParticipant preparedPart;
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private StorableObject storedpart;
>>> +    private final StorableObject storedpart;
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private long crashcount = 0;
>>> +    private volatile long crashcount = 0;
>>> 
>>>   /**
>>>    * @serial
>>> @@ -70,6 +70,7 @@
>>>       if (preparedPart == null) 
>>> 	    throw new NullPointerException(
>>> 	        "TransactionParticipant argument cannot be null");
>>> +        StorableObject storedpart = null;
>>> 	try {
>>> 	    storedpart = new StorableObject(preparedPart);
>>> 	    this.preparedPart = preparedPart;
>>> @@ -80,6 +81,7 @@
>>> 		    "Cannot store the TransactionParticipant", re);
>>> 	    }
>>> 	}
>>> +        this.storedpart = storedpart;
>>> 	this.prepstate = ACTIVE;
>>>   }
>>> 
>>> Index: src/com/sun/jini/mahalo/ParticipantModRecord.java
>>> --- src/com/sun/jini/mahalo/ParticipantModRecord.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/ParticipantModRecord.java Locally Modified (Based On LOCAL)
>>> @@ -38,12 +38,12 @@
>>>   /**
>>>    * @serial
>>>    */
>>> -    private ParticipantHandle part;
>>> +    private final ParticipantHandle part;
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private int result;
>>> +    private final int result;
>>> 
>>>   ParticipantModRecord(ParticipantHandle part, int result) {
>>> 	if (part == null)
>>> Index: src/com/sun/jini/mahalo/ParticipantTask.java
>>> --- src/com/sun/jini/mahalo/ParticipantTask.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/ParticipantTask.java Locally Modified (Based On LOCAL)
>>> @@ -17,6 +17,7 @@
>>> */
>>> package com.sun.jini.mahalo;
>>> 
>>> +import com.sun.jini.logging.Levels;
>>> import com.sun.jini.thread.RetryTask;
>>> import com.sun.jini.thread.TaskManager;
>>> import com.sun.jini.thread.WakeupManager;
>>> @@ -35,8 +36,8 @@
>>> * @see TaskManager
>>> */
>>> public class ParticipantTask extends RetryTask {
>>> -    ParticipantHandle handle;
>>> -    Job myjob;
>>> +    final ParticipantHandle handle;
>>> +    final Job myjob;
>>>   private static final Logger operationsLogger = 
>>>       TxnManagerImpl.operationsLogger;
>>> 	
>>> @@ -81,9 +82,11 @@
>>> 	} catch (UnknownTaskException ute) {
>>> 	    //If task doesn't belong to the
>>> 	    //Job, then stop doing work.
>>> +            logger.log(Level.FINE, "Task didn't belong to job",ute);
>>> +            ute.printStackTrace(System.err);
>>> 	    result = true;
>>> 	} catch (JobException je) {
>>> -	    je.printStackTrace();
>>> +	    je.printStackTrace(System.err);
>>> 	}
>>>       if (operationsLogger.isLoggable(Level.FINER)) {
>>>           operationsLogger.exiting(ParticipantTask.class.getName(), 
>>> Index: src/com/sun/jini/mahalo/PrepareAndCommitJob.java
>>> --- src/com/sun/jini/mahalo/PrepareAndCommitJob.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/PrepareAndCommitJob.java Locally Modified (Based On LOCAL)
>>> @@ -45,10 +45,10 @@
>>> * @see net.jini.core.transaction.server.TransactionParticipant
>>> */
>>> public class PrepareAndCommitJob extends Job implements TransactionConstants {
>>> -    ServerTransaction tr;
>>> -    ClientLog log;
>>> -    ParticipantHandle handle;
>>> -    int maxtries = 5;
>>> +    final ServerTransaction tr;
>>> +    final ClientLog log;
>>> +    final ParticipantHandle handle;
>>> +    final int maxtries = 5;
>>> 
>>>   /*
>>>    * Field that holds the last received remote exception, if any.
>>> @@ -290,7 +290,9 @@
>>> 
>>> 	int prepstate = NOTCHANGED;
>>> 
>>> -	prepstate = ((Integer)results[0]).intValue();
>>> +        synchronized (this){
>>> +            prepstate = ((Integer) results.get(Integer.valueOf(0))).intValue();
>>> +        }
>>> 
>>>       Integer result = Integer.valueOf(prepstate);
>>>       if (operationsLogger.isLoggable(Level.FINER)) {
>>> Index: src/com/sun/jini/mahalo/PrepareJob.java
>>> --- src/com/sun/jini/mahalo/PrepareJob.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/PrepareJob.java Locally Modified (Based On LOCAL)
>>> @@ -22,6 +22,7 @@
>>> import com.sun.jini.thread.TaskManager;
>>> import com.sun.jini.thread.WakeupManager;
>>> import java.rmi.RemoteException;
>>> +import java.util.Iterator;
>>> import java.util.logging.Level;
>>> import java.util.logging.Logger;
>>> import net.jini.core.transaction.Transaction;
>>> @@ -273,10 +274,11 @@
>>> 	int prepstate = NOTCHANGED;
>>> 	int tmp = 0;
>>> 
>>> -	checkresults:
>>> -	for (int i = 0; i < results.length; i++) {
>>> -	    tmp = ((Integer)results[i]).intValue();
>>> -
>>> +        synchronized (this){
>>> +            Iterator i = results.values().iterator();
>>> +            checkresult:
>>> +            while (i.hasNext()){
>>> +                tmp = ((Integer) i.next()).intValue();
>>> 	    switch(tmp) {
>>> 	      case NOTCHANGED:
>>> 		//Does not affect the prepstate
>>> @@ -288,7 +290,7 @@
>>> 		//aborts the whole transaction.
>>> 
>>> 		prepstate = ABORTED;
>>> -		break checkresults;
>>> +                    break checkresult;
>>> 
>>> 	      case PREPARED:
>>> 		//changes the state to PREPARED only
>>> @@ -298,11 +300,13 @@
>>> 		break;
>>> 	    }
>>> 	}
>>> -	Integer result = Integer.valueOf(prepstate);
>>> +        }
>>> +        
>>> +	Integer r = Integer.valueOf(prepstate);
>>>       if (operationsLogger.isLoggable(Level.FINER)) {
>>>           operationsLogger.exiting(PrepareJob.class.getName(),
>>> -                "computeResult", result);
>>> +                "computeResult", r);
>>> 	}
>>> -	return result;
>>> +	return r;
>>>   }
>>> }
>>> Index: src/com/sun/jini/mahalo/SettlerTask.java
>>> --- src/com/sun/jini/mahalo/SettlerTask.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/SettlerTask.java Locally Modified (Based On LOCAL)
>>> @@ -39,10 +39,10 @@
>>> */
>>> 
>>> public class SettlerTask extends RetryTask implements TransactionConstants {
>>> -    private long tid;
>>> -    private int attempt;
>>> -    private int maxtries = Integer.MAX_VALUE;
>>> -    private TransactionManager txnmgr;
>>> +    private final long tid;
>>> +    private int attempt; // sync on this.
>>> +    private final int maxtries = Integer.MAX_VALUE;
>>> +    private final TransactionManager txnmgr;
>>> 
>>>   /** Logger for operations related messages */
>>>   private static final Logger operationsLogger = 
>>> @@ -89,10 +89,12 @@
>>> 	        "tryOnce");
>>> 	}
>>>       try {
>>> +            synchronized (this){
>>> 	    if (attempt >= maxtries)
>>> 		return true;
>>> 
>>> 	    attempt++;
>>> +            }
>>> 
>>> 	    if (transactionsLogger.isLoggable(Level.FINEST)) {
>>>               transactionsLogger.log(Level.FINEST,
>>> Index: src/com/sun/jini/mahalo/StorableObject.java
>>> --- src/com/sun/jini/mahalo/StorableObject.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/StorableObject.java Locally Modified (Based On LOCAL)
>>> @@ -19,6 +19,7 @@
>>> package com.sun.jini.mahalo;
>>> 
>>> import java.io.IOException;
>>> +import java.io.ObjectInputStream;
>>> import java.rmi.MarshalledObject;
>>> import java.rmi.RemoteException;
>>> 
>>> @@ -39,8 +40,8 @@
>>>   /**
>>>    * @serial
>>>    */
>>> -    private MarshalledObject	bytes;	// the serialized bytes
>>> -    private transient Object	obj;	// the cached object reference
>>> +    private final MarshalledObject	bytes;	// the serialized bytes
>>> +    private volatile transient Object	obj;	// the cached object reference
>>> 
>>>   private static final boolean DEBUG = false;
>>>   private static final long serialVersionUID = -3793675220968988873L;
>>> @@ -50,16 +51,25 @@
>>>    * in a <code>MarshalledObject</code>.
>>>    */
>>>   public StorableObject(Object obj) throws RemoteException {
>>> +	this(obj, toMO(obj));
>>> +    }
>>> +    
>>> +    private static MarshalledObject toMO(Object obj) throws RemoteException{
>>> 	try {
>>> -	    bytes = new MarshalledObject(obj);
>>> -	    this.obj = obj;
>>> -	} catch (RemoteException e) {
>>> +            return new MarshalledObject(obj);
>>> +        } catch (RemoteException e){
>>> 	    throw e;
>>> -	} catch (IOException e) {
>>> +        } catch (IOException e){
>>> 	    fatalError("can't encode object", e);
>>> 	}
>>> +        return null; //Unreachable.
>>>   }
>>> 
>>> +    private StorableObject (Object obj, MarshalledObject mo){
>>> +        bytes = mo;
>>> +        this.obj = obj;
>>> +    }
>>> +    
>>>   /**
>>>    * Return the <code>hashCode</code> of the <code>MarshalledObject</code>.
>>>    */
>>> @@ -103,6 +113,12 @@
>>> 	return null;	// not reached, but compiler doesn't know
>>>   }
>>> 
>>> +    private void readObject(ObjectInputStream s)
>>> +                                   throws IOException, ClassNotFoundException
>>> +        {
>>> +            s.defaultReadObject(); // Just in case we change serial form later.
>>> +        }
>>> +
>>>   /**
>>>    * Unrecoverable error happened -- show it and give up the ghost.
>>>    */
>>> Index: src/com/sun/jini/mahalo/TxnManagerImpl.java
>>> --- src/com/sun/jini/mahalo/TxnManagerImpl.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/TxnManagerImpl.java Locally Modified (Based On LOCAL)
>>> @@ -62,6 +62,7 @@
>>> import java.util.Iterator;
>>> import java.util.Map;
>>> import java.util.Vector;
>>> +import java.util.concurrent.ConcurrentMap;
>>> import java.util.logging.Level;
>>> import java.util.logging.Logger;
>>> 
>>> @@ -149,28 +150,6 @@
>>>   static final Logger persistenceLogger = 
>>>       Logger.getLogger(TxnManager.MAHALO + ".persistence");
>>> 
>>> -    /* At some point earlier in the development, it appears this object
>>> -     * was Serializable, or was declared so, such that it replaced itself
>>> -     * with a proxy stub.  This is a test to ensure serialization doesn't
>>> -     * occur.
>>> -     */
>>> -    
>>> -    private void writeObject(java.io.ObjectOutputStream out)
>>> -     throws IOException {
>>> -        throw new IOException("Serialization not supported");
>>> -    }
>>> -    private void readObject(java.io.ObjectInputStream in)
>>> -     throws IOException, ClassNotFoundException {
>>> -        throw new IOException("Serialization not supported");
>>> -    }
>>> -    private void readObjectNoData() 
>>> -     throws ObjectStreamException{
>>> -        throw new ObjectStreamException("Serialization not supported"){
>>> -            private static final long serialVersionUID = 1L;
>>> -        };
>>> -    }
>>> - 
>>> -    
>>>   private volatile LogManager logmgr;
>>>   /* Retrieve values from properties.          */
>>>   /* Its important here to schedule SettlerTasks on a */
>>> @@ -186,7 +165,7 @@
>>>   private final WakeupManager taskWakeupMgr;
>>>   /* Map of transaction ids are their associated, internal 
>>>    * transaction representations */
>>> -    private final Map<Long,TxnManagerTransaction> txns;
>>> +    private final ConcurrentMap<Long,TxnManagerTransaction> txns;
>>>   private final Vector<Long> unsettledtxns = new Vector<Long>();
>>>   private final InterruptedStatusThread settleThread;
>>>   private final String persistenceDirectory;
>>> @@ -390,7 +369,7 @@
>>>               settleThread = init.settleThread;
>>>           } else {
>>>               // Assign init fields
>>> -                txns = Collections.emptyMap();
>>> +                txns = null;
>>>               /* Retrieve values from properties.          */
>>>               activationSystem = null;
>>>               activationID = activID;
>>> @@ -627,8 +606,7 @@
>>> 	        "prepared participant: {0}", preparedTarget);
>>> 	}
>>> 
>>> -        TxnManagerTransaction txntr =
>>> -		(TxnManagerTransaction) txns.get(Long.valueOf(id));
>>> +        TxnManagerTransaction txntr = txns.get(Long.valueOf(id));
>>> 
>>> 	if (txntr == null)
>>> 	    throw new UnknownTransactionException("unknown transaction");
>>> @@ -645,6 +623,7 @@
>>>   public int getState(long id)
>>>       throws UnknownTransactionException
>>>   {
>>> +        
>>>       if (operationsLogger.isLoggable(Level.FINER)) {
>>>           operationsLogger.entering(
>>> 		TxnManagerImpl.class.getName(), "getState", 
>>> @@ -652,9 +631,8 @@
>>> 	}
>>>       readyState.check();
>>> 
>>> -        TxnManagerTransaction txntr =
>>> -	        (TxnManagerTransaction) txns.get(Long.valueOf(id));
>>> -
>>> +        TxnManagerTransaction txntr = null;
>>> +                txntr = txns.get(Long.valueOf(id));
>>> 	if (txntr == null)
>>> 	    throw new UnknownTransactionException("unknown transaction");
>>>       /* Expiration checks are only meaningful for active transactions. */
>>> @@ -669,17 +647,18 @@
>>> 	 * a false result.
>>> 	 */
>>> //TODO - need better locking here. getState and expiration need to be checked atomically	
>>> -        int state = txntr.getState();
>>> -        if (state == ACTIVE && !ensureCurrent(txntr)) 
>>> -	    throw new UnknownTransactionException("unknown transaction");
>>> -	    
>>> +        try{
>>> +            int state = txntr.atomicCheckExpirationIfActive();
>>> 	if (operationsLogger.isLoggable(Level.FINER)) {
>>>           operationsLogger.exiting(
>>> 		TxnManagerImpl.class.getName(), "getState", 
>>> 	        Integer.valueOf(state));
>>> 	}
>>> 	return state;
>>> +        } catch (TransactionException ex) {
>>> +            throw new UnknownTransactionException("unknown transaction");
>>>   }
>>> +    }
>>> 
>>> 
>>>   public void commit(long id)
>>> @@ -901,12 +880,14 @@
>>>                   transactionsLogger.log(Level.FINEST,
>>>                       "Settler waiting");
>>> 	        }
>>> -		wait();
>>> -
>>> -	        if (transactionsLogger.isLoggable(Level.FINEST)) {
>>> -                    transactionsLogger.log(Level.FINEST,
>>> -                        "Settler notified");
>>> -	        }
>>> +                // Don't wait forever, in case we're not notified, break out
>>> +                // early and check condition.
>>> +		wait(10000L); 
>>> +                // Due to spurious wakeup and break out after ten seconds, the following log message is inaccurate.
>>> +//	        if (transactionsLogger.isLoggable(Level.FINEST)) {
>>> +//                    transactionsLogger.log(Level.FINEST,
>>> +//                        "Settler notified");
>>> +//	        }
>>> 		continue;
>>> 	    }
>>> 
>>> @@ -1018,6 +999,7 @@
>>> 
>>> 	// synchronize on the resource so there is not a race condition
>>> 	// between renew and expiration
>>> +        /* TODO check if synchronization correct */
>>> 	Result r;
>>> 	synchronized (txntr) {
>>> //TODO - check for ACTIVE too?
>>> @@ -1066,7 +1048,7 @@
>>> 
>>>       try {
>>>           // getState and expiration checked atomically
>>> -            txntr.checkStateActive(); // Throws UnknownLeaseException if state not ACTIVE.
>>> +            txntr.atomicCheckStateActive(); // throws TransactionException if state not ACTIVE.
>>>           // State is still active, make it expire.
>>>           txntr.setExpiration(0);	// Mark as done
>>>           abort(((Long)tid).longValue(), false);
>>> Index: src/com/sun/jini/mahalo/TxnManagerImplInitializer.java
>>> --- src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Locally Modified (Based On LOCAL)
>>> @@ -38,6 +38,8 @@
>>> import java.util.HashMap;
>>> import java.util.Iterator;
>>> import java.util.Map;
>>> +import java.util.concurrent.ConcurrentHashMap;
>>> +import java.util.concurrent.ConcurrentMap;
>>> import java.util.logging.Level;
>>> import net.jini.activation.ActivationExporter;
>>> import net.jini.config.Configuration;
>>> @@ -64,7 +66,7 @@
>>>   int taskthreads = 50;
>>>   long tasktimeout = 1000 * 15;
>>>   float taskload = 1.0F;
>>> -    Map<Long, TxnManagerTransaction> txns = Collections.synchronizedMap(new HashMap<Long, TxnManagerTransaction>());
>>> +    ConcurrentMap<Long, TxnManagerTransaction> txns = new ConcurrentHashMap<Long, TxnManagerTransaction>();
>>>   /* Retrieve values from properties.          */
>>>   ActivationSystem activationSystem = null;
>>>   boolean activationPrepared = false;
>>> Index: src/com/sun/jini/mahalo/TxnManagerTransaction.java
>>> --- src/com/sun/jini/mahalo/TxnManagerTransaction.java Base (BASE)
>>> +++ src/com/sun/jini/mahalo/TxnManagerTransaction.java Locally Modified (Based On LOCAL)
>>> @@ -135,17 +135,17 @@
>>>   /**
>>>    * @serial
>>>    */
>>> -    private int trstate;
>>> +    private int trstate; //sync on stateLock
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private long expires;		//expiration time
>>> +    private long expires;		//expiration time sync on leaseLock
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private LogManager logmgr;
>>> +    private final LogManager logmgr;
>>> 
>>> 
>>>  /**
>>> @@ -180,27 +180,27 @@
>>>   *
>>>   * @serial
>>>   */
>>> -    private TaskManager threadpool;
>>> +    private final TaskManager threadpool;
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private WakeupManager wm;
>>> +    private final WakeupManager wm;
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private TxnSettler settler;
>>> +    private final TxnSettler settler;
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private Job job;
>>> +    private Job job; // sync with jobLock
>>> 
>>>   /**
>>>    * @serial
>>>    */
>>> -    private Uuid uuid;
>>> +    private final Uuid uuid;
>>> 
>>>  /**
>>>   * Interlock for the expiration time since
>>> @@ -524,12 +524,21 @@
>>> 	}
>>>   }
>>> 
>>> +    public int atomicCheckExpirationIfActive() throws TransactionException {
>>> +        synchronized (stateLock){
>>> +            int state = getState();
>>> +            if (state == ACTIVE && !(getExpiration() > System.currentTimeMillis())) 
>>> +                throw new TransactionException("unknown transaction");
>>> +            return state;
>>> +        }
>>> +    }
>>> +
>>>   /**
>>>    * Atomic check that state is ACTIVE.
>>>    * @return ACTIVE if lease hasn't expired.
>>>    * @throws TransactionException otherwise.
>>>    */
>>> -    public int checkStateActive() throws TransactionException {
>>> +    public int atomicCheckStateActive() throws TransactionException {
>>>       synchronized (stateLock){
>>>           int state = getState();
>>>           if ((state == ACTIVE && getExpiration()==0) || (state != ACTIVE)) {
>>> @@ -839,13 +848,15 @@
>>> 								"ABORTED");
>>> 		  }
>>> 
>>> -                  if (getState() != COMMITTED)
>>> +                  if (getState() != COMMITTED){
>>> +                      synchronized (jobLock){
>>>                       throw new
>>>                           InternalManagerException("TxnManagerTransaction: " +
>>>                                   "commit: " + job + " got bad state: " +
>>>                                   TxnConstants.getName(result.intValue()));
>>> +                      }
>>> +                  }
>>> 
>>> -
>>> 		now = System.currentTimeMillis();
>>> 		transpired = now - starttime;
>>> 
>>> Index: src/com/sun/jini/mercury/MailboxImpl.java
>>> --- src/com/sun/jini/mercury/MailboxImpl.java Base (BASE)
>>> +++ src/com/sun/jini/mercury/MailboxImpl.java Locally Modified (Based On LOCAL)
>>> @@ -419,7 +419,7 @@
>>>   // constructor thread and set to null after starting.
>>>   private Configuration config;
>>>   private Throwable thrown;
>>> -    private volatile boolean started = false;
>>> +    private boolean started = false;
>>> 
>>>   ///////////////////////
>>>   // Activation Methods
>>> @@ -1071,8 +1071,8 @@
>>> //    } // End doInit()
>>> //    
>>>   public void start() throws Exception {
>>> -        if (started) return;
>>>       concurrentObj.writeLock();
>>> +        if (started) return;
>>>       started = true; // mutual exclusion
>>>       try {
>>>           if (thrown != null) throw thrown;
>>> Index: src/com/sun/jini/outrigger/EventRegistrationWatcher.java
>>> --- src/com/sun/jini/outrigger/EventRegistrationWatcher.java Base (BASE)
>>> +++ src/com/sun/jini/outrigger/EventRegistrationWatcher.java Locally Modified (Based On LOCAL)
>>> @@ -240,7 +240,7 @@
>>>    * @return The unique identifier associated with this
>>>    * watcher.
>>>    */
>>> -    public Uuid getCookie() {
>>> +    public synchronized Uuid getCookie() {
>>> 	return cookie;
>>>   }
>>> 
>>> Index: src/com/sun/jini/outrigger/OutriggerServerImpl.java
>>> --- src/com/sun/jini/outrigger/OutriggerServerImpl.java Base (BASE)
>>> +++ src/com/sun/jini/outrigger/OutriggerServerImpl.java Locally Modified (Based On LOCAL)
>>> @@ -647,6 +647,7 @@
>>>       if (except != null) throw except;
>>>       try {
>>>           // This takes a while the first time, so let's get it going
>>> +            txnMonitor.start();
>>>           starter.start();
>>> 
>>>           // Get store from configuration
>>> Index: src/com/sun/jini/outrigger/StorableEventWatcher.java
>>> --- src/com/sun/jini/outrigger/StorableEventWatcher.java Base (BASE)
>>> +++ src/com/sun/jini/outrigger/StorableEventWatcher.java Locally Modified (Based On LOCAL)
>>> @@ -36,7 +36,7 @@
>>>   implements StorableResource
>>> {
>>>   /** The listener that should be notified of matches */
>>> -    private StorableReference listener;
>>> +    private volatile StorableReference listener;
>>> 
>>>   /**
>>>    * Used during log recovery to create a mostly empty
>>> @@ -115,7 +115,7 @@
>>>    * @param expired <code>true</code> if being called from 
>>>    *        <code>removeIfExpired</code> and false otherwise. 
>>>    */
>>> -    void cleanup(TemplateHandle owner, boolean expired) {
>>> +    synchronized void cleanup(TemplateHandle owner, boolean expired) {
>>> 	if (expired)
>>> 	    owner.getServer().scheduleCancelOp(cookie);
>>> 	else 
>>> @@ -126,7 +126,7 @@
>>>   /**  
>>>    * Store the persistent fields 
>>>    */
>>> -    public void store(ObjectOutputStream out) throws IOException {
>>> +    public synchronized void store(ObjectOutputStream out) throws IOException {
>>> 	cookie.write(out);
>>> 	out.writeLong(expiration);
>>> 	out.writeLong(eventID);
>>> @@ -137,7 +137,7 @@
>>>   /**
>>>    * Restore the persistent fields
>>>    */
>>> -    public void restore(ObjectInputStream in) 
>>> +    public synchronized void restore(ObjectInputStream in) 
>>> 	throws IOException, ClassNotFoundException 
>>>   {
>>> 	cookie = UuidFactory.read(in);
>>> Index: src/com/sun/jini/outrigger/TxnMonitor.java
>>> --- src/com/sun/jini/outrigger/TxnMonitor.java Base (BASE)
>>> +++ src/com/sun/jini/outrigger/TxnMonitor.java Locally Modified (Based On LOCAL)
>>> @@ -51,8 +51,8 @@
>>>    * @see #pending
>>>    */
>>>   private static class ToMonitor {
>>> -	QueryWatcher	query;         // query governing interest in txns
>>> -	Collection	txns;	       // the transactions to monitor
>>> +	final QueryWatcher	query;         // query governing interest in txns
>>> +	final Collection	txns;	       // the transactions to monitor
>>> 
>>> 	ToMonitor(QueryWatcher query, Collection txns) {
>>> 	    this.query = query;
>>> @@ -71,7 +71,7 @@
>>>    * @see OutriggerServerImpl#getMatch 
>>>    */
>>>   // @see #ToMonitor
>>> -    private LinkedList pending = new LinkedList();
>>> +    private final LinkedList pending = new LinkedList();
>>> 
>>>   /** wakeup manager for <code>TxnMonitorTask</code>s */
>>>   private final WakeupManager wakeupMgr = 
>>> @@ -80,21 +80,23 @@
>>>   /**
>>>    * The manager for <code>TxnMonitorTask</code> objects.
>>>    */
>>> -    private TaskManager taskManager;
>>> +    private final TaskManager taskManager;
>>> 
>>>   /**
>>>    * The space we belong to.  Needed for aborts.
>>>    */
>>> -    private OutriggerServerImpl	space;
>>> +    private final OutriggerServerImpl	space;
>>> 
>>>   /**
>>>    * The thread running us.
>>>    */
>>> -    private Thread ourThread;
>>> +    private final Thread ourThread;
>>> 
>>>   /** Set when we are told to stop */
>>> -    private boolean die = false;
>>> +    private volatile boolean die = false;
>>> 
>>> +    private volatile boolean started = false;
>>> +
>>>   /** Logger for logging transaction related information */
>>>   private static final Logger logger = 
>>> 	Logger.getLogger(OutriggerServerImpl.txnLoggerName);
>>> @@ -115,8 +117,15 @@
>>> 
>>>       ourThread = new Thread(this, "TxnMonitor");
>>> 	ourThread.setDaemon(true);
>>> +//        ourThread.start();
>>> +    }
>>> +    
>>> +    public void start(){
>>> +        synchronized (this){
>>>       ourThread.start();
>>> +            started = true;
>>>   }
>>> +    }
>>> 
>>>   public void destroy() {
>>>       taskManager.terminate();
>>> @@ -128,7 +137,7 @@
>>> 	}
>>> 
>>>       try {
>>> -	    ourThread.join();
>>> +	    if (started) ourThread.join();
>>> 	} catch(InterruptedException ie) {
>>> 	    // ignore
>>> 	}
>>> Index: src/com/sun/jini/outrigger/TypeTree.java
>>> --- src/com/sun/jini/outrigger/TypeTree.java Base (BASE)
>>> +++ src/com/sun/jini/outrigger/TypeTree.java Locally Modified (Based On LOCAL)
>>> @@ -39,7 +39,7 @@
>>> */
>>> class TypeTree {
>>>   /** For each type, a vector of known subtypes */
>>> -    private Hashtable subclasses = new Hashtable();
>>> +    private final Hashtable<String,Vector> subclasses = new Hashtable<String,Vector>();
>>> 
>>>   /**
>>>    * A generator used to randomize the order of iterator returns
>>> @@ -57,8 +57,10 @@
>>>    * Return the vector of subclasses for the given class.
>>>    */
>>>   private Vector classVector(String whichClass) {
>>> +        synchronized (subclasses){
>>> 	return (Vector) subclasses.get(whichClass);
>>>   }
>>> +    }
>>> 
>>>   /**
>>>    * An iterator that will walk through a list of known types.
>>> Index: src/com/sun/jini/thread/RetryTask.java
>>> --- src/com/sun/jini/thread/RetryTask.java Base (BASE)
>>> +++ src/com/sun/jini/thread/RetryTask.java Locally Modified (Based On LOCAL)
>>> @@ -64,7 +64,7 @@
>>> import com.sun.jini.thread.WakeupManager.Ticket;
>>> 
>>> public abstract class RetryTask implements TaskManager.Task, TimeConstants {
>>> -    private TaskManager	  manager;	// the TaskManager for this task
>>> +    private final TaskManager	  manager;	// the TaskManager for this task
>>>   private RetryTime	  retry;	// the retry object for this task
>>>   private boolean	  cancelled;	// have we been cancelled?
>>>   private boolean	  complete;	// have we completed successfully?
>>> @@ -72,7 +72,7 @@
>>>   private long	  startTime;	// the time when we were created or 
>>>                                       //   last reset
>>>   private int		  attempt;	// the current attempt number
>>> -    private WakeupManager wakeup;       // WakeupManager for retry scheduling
>>> +    private final WakeupManager wakeup;       // WakeupManager for retry scheduling
>>> 
>>>   /**
>>>    * Default delay backoff times.  These are converted from
>>> @@ -91,7 +91,7 @@
>>>   };
>>> 
>>>   /** Logger for this class */
>>> -    private static final Logger logger = 
>>> +    protected static final Logger logger = 
>>> 	Logger.getLogger("com.sun.jini.thread.RetryTask");
>>> 
>>>   /**
>>> @@ -128,7 +128,14 @@
>>> 		return;			// do nothing
>>> 	}
>>> 
>>> -	boolean success = tryOnce();
>>> +	boolean success = false;
>>> +        try {
>>> +            success = tryOnce();
>>> +        } catch (Throwable t){
>>> +            t.printStackTrace(System.err);
>>> +            if (t instanceof Error) throw (Error) t;
>>> +            if (t instanceof RuntimeException) throw (RuntimeException) t;
>>> +        }
>>> 
>>> 	synchronized (this) {
>>> 	    if (!success) {		// if at first we don't succeed ...
>>> Index: src/com/sun/jini/thread/TaskManager.java
>>> --- src/com/sun/jini/thread/TaskManager.java Base (BASE)
>>> +++ src/com/sun/jini/thread/TaskManager.java Locally Modified (Based On LOCAL)
>>> @@ -22,6 +22,7 @@
>>> import java.util.Collections;
>>> import java.util.Iterator;
>>> import java.util.List;
>>> +import java.util.concurrent.CopyOnWriteArrayList;
>>> import java.util.logging.Level;
>>> import java.util.logging.Logger;
>>> 
>>> @@ -77,13 +78,13 @@
>>> 	Logger.getLogger("com.sun.jini.thread.TaskManager");
>>> 
>>>   /** Active and pending tasks */
>>> -    protected final ArrayList tasks = new ArrayList();
>>> +    protected final ArrayList tasks = new ArrayList(); //sync on this
>>>   /** Index of the first pending task; all earlier tasks are active */
>>> -    protected int firstPending = 0;
>>> +    protected int firstPending = 0;//sync on this
>>>   /** Read-only view of tasks */
>>> -    protected final List roTasks = Collections.unmodifiableList(tasks);
>>> +    protected final List roTasks = Collections.unmodifiableList(tasks); // sync on this
>>>   /** Active threads */
>>> -    protected final List threads = new ArrayList();
>>> +    protected final List threads = new ArrayList(); //sync on this
>>>   /** Maximum number of threads allowed */
>>>   protected final int maxThreads;
>>>   /** Idle time before a thread should exit */
>>> @@ -91,7 +92,7 @@
>>>   /** Threshold for creating new threads */
>>>   protected final float loadFactor;
>>>   /** True if manager has been terminated */
>>> -    protected boolean terminated = false;
>>> +    protected boolean terminated = false; //sync on this
>>> 
>>>   /**
>>>    * Create a task manager with maxThreads = 10, timeout = 15 seconds,
>>> @@ -256,7 +257,7 @@
>>> 
>>>   /** Return all pending tasks.  A new list is returned each time. */
>>>   public synchronized ArrayList getPending() {
>>> -	ArrayList tc = (ArrayList)tasks.clone();
>>> +	ArrayList tc = new ArrayList(tasks);
>>> 	for (int i = firstPending; --i >= 0; ) {
>>> 	    tc.remove(0);
>>> 	}
>>> @@ -271,7 +272,7 @@
>>>   private class TaskThread extends Thread {
>>> 
>>> 	/** The task being run, if any */
>>> -	public Task task = null;
>>> +	public Task task = null; // sync access on TaskManager.this
>>> 
>>> 	public TaskThread() {
>>> 	    super("task");
>>> @@ -303,6 +304,7 @@
>>> 
>>> 	public void run() {
>>> 	    while (true) {
>>> +                Task tsk = null;
>>> 		synchronized (TaskManager.this) {
>>> 		    if (terminated)
>>> 			return;
>>> @@ -327,9 +329,10 @@
>>> 			    return;
>>> 			}
>>> 		    }
>>> +                    tsk = task;  
>>> 		}
>>> 		try {
>>> -		    task.run();
>>> +		    tsk.run();
>>> 		} catch (Throwable t) {
>>> 		    try {
>>> 			logger.log(Level.WARNING, "Task.run exception", t);
>>> Index: src/com/sun/jini/thread/WakeupManager.java
>>> --- src/com/sun/jini/thread/WakeupManager.java Base (BASE)
>>> +++ src/com/sun/jini/thread/WakeupManager.java Locally Modified (Based On LOCAL)
>>> @@ -493,7 +493,7 @@
>>>    * Assumes the caller holds the lock on contents.
>>>    */
>>>   private void checkHead() {
>>> -	assert Thread.holdsLock(contents);
>>> +        synchronized (contents){
>>> 	final Ticket oldHead = head;
>>> 
>>> 	if (contents.isEmpty())
>>> @@ -507,6 +507,7 @@
>>> 	// needs to wake up and change its sleep time.
>>> 	contents.notifyAll();
>>>   }
>>> +    }
>>> 
>>>   /**
>>>    * Return whether the queue is currently empty.
>>> Index: src/net/jini/lookup/JoinManager.java
>>> --- src/net/jini/lookup/JoinManager.java Base (BASE)
>>> +++ src/net/jini/lookup/JoinManager.java Locally Modified (Based On LOCAL)
>>> @@ -563,10 +563,11 @@
>>>   private class ProxyRegTask extends RetryTask {
>>>       private final long[] sleepTime = { 5*1000, 10*1000, 15*1000,
>>>                                         20*1000, 25*1000, 30*1000 };
>>> -        protected int tryIndx  = 0;
>>> -        protected int nRetries = 0;
>>> -        protected ProxyReg proxyReg;
>>> -        protected int seqN;
>>> +        // volatile fields only mutated while synchronized on proxyReg.taskList
>>> +        private volatile int tryIndx  = 0;
>>> +        private volatile int nRetries = 0;
>>> +        private final ProxyReg proxyReg;
>>> +        private volatile int seqN;
>>> 
>>>       /** Basic constructor; simply stores the input parameters */
>>>       ProxyRegTask(ProxyReg proxyReg, int seqN) {
>>> @@ -611,10 +612,11 @@
>>>                       if( !proxyReg.taskList.isEmpty() ) {
>>>                           proxyReg.taskList.remove(0);
>>>                       }//endif
>>> -                    }//end sync
>>>                   /* reset the retry info for the next task in the list */
>>>                   tryIndx  = 0;
>>>                   nRetries = 0;
>>> +                    }//end sync
>>> +                    
>>>               } catch (Exception e) {
>>>                   return stopTrying(e);
>>>               }
>>> @@ -627,8 +629,10 @@
>>>        */
>>>       public long retryTime() {
>>> 	    long nextTryTime = System.currentTimeMillis() + sleepTime[tryIndx];
>>> +            synchronized (proxyReg.taskList){
>>> 	    if(tryIndx < sleepTime.length-1)  tryIndx++;//don't go past end
>>>           nRetries++;
>>> +            }
>>>           return nextTryTime;
>>>       }//end retryTime
>>> 
>>> @@ -737,7 +741,7 @@
>>>   private abstract class JoinTask {
>>> 
>>>       /** Data structure referencing the task's associated lookup service */
>>> -        protected ProxyReg proxyReg;
>>> +        protected final ProxyReg proxyReg;
>>> 
>>>       /** Basic constructor; simply stores the input parameters */
>>>       JoinTask(ProxyReg proxyReg) {
>>> @@ -758,7 +762,7 @@
>>>        *  must not change during the registration process performed in
>>>        *  this this task.
>>>        */
>>> -        Entry[] regAttrs;
>>> +        final Entry[] regAttrs;
>>> 
>>>       /** Constructor that associates this task with the lookup service
>>>        *  referenced in the given <code>ProxyReg</code> parameter.
>>> @@ -889,9 +893,10 @@
>>>        */
>>>       public void run() {
>>>           logger.finest("JoinManager --> DiscardProxyTask started");
>>> -            if( (proxyReg != null) && (proxyReg.serviceLease != null) ) {
>>> +            Lease svcLease = proxyReg != null ? proxyReg.serviceLease : null;
>>> +            if( svcLease != null ) {
>>>               try {
>>> -                    proxyReg.serviceLease.cancel();
>>> +                    svcLease.cancel();
>>>               } catch (Exception e) { /*ignore*/ }
>>>           }//endif
>>>           logger.finest("JoinManager - DiscardProxyTask completed");
>>> @@ -1140,31 +1145,34 @@
>>>       /** The <code>ProxyRegTask</code> that instantiated this
>>>        *  <code>ProxyReg</code>.
>>>        */
>>> -        public ProxyRegTask proxyRegTask;
>>> +        volatile ProxyRegTask proxyRegTask;
>>>       /** The <i>prepared</i> proxy to the lookup service referenced by
>>>        *  this class, and with which this join manager's service will be
>>>        *  registered.
>>>        */
>>> -	public ServiceRegistrar proxy;
>>> +	final ServiceRegistrar proxy;
>>>       /** The <i>prepared</i> registration proxy returned by this class'
>>>        *  associated lookup service when this join manager registers its
>>>        *  associated service.
>>> +         * 
>>> +         * Access to reference synchronized on joinSet, but not referent
>>> +         * as it has foreign remote methods.
>>>        */
>>> -	public ServiceRegistration srvcRegistration = null;
>>> +	ServiceRegistration srvcRegistration = null;
>>>       /* The <i>prepared</i> proxy to the lease on the registration of this
>>>        * join manager's service with the this class' associated lookup
>>>        * service.
>>>        */
>>> -	public Lease serviceLease = null;
>>> +	volatile Lease serviceLease = null;
>>>       /** The set of sub-tasks that are to be executed in order for the
>>>        *  lookup service associated with the current instance of this class.
>>>        */
>>> -        public List taskList = new ArrayList(1);
>>> +        final List taskList = new ArrayList(1);
>>>       /** The instance of <code>DiscLeaseListener</code> that is registered
>>>        *  with the lease renewal manager that handles the lease of this join
>>>        *  manger's service.
>>>        */
>>> -	private DiscLeaseListener dListener = new DiscLeaseListener();
>>> +	private final DiscLeaseListener dListener = new DiscLeaseListener();
>>> 
>>>       /** Constructor that associates this class with the lookup service
>>>        *  referenced in the given <code>ProxyReg</code> parameter.
>>> @@ -1236,19 +1244,19 @@
>>>               throw e; //rethrow the exception since proxy may be unusable
>>>           }
>>>           /* Retrieve and prepare the proxy to the service lease */
>>> -            serviceLease = tmpSrvcRegistration.getLease();
>>> +            Lease svcLease = tmpSrvcRegistration.getLease();
>>>           try {
>>> -                serviceLease = 
>>> -                       (Lease)serviceLeasePreparer.prepareProxy(serviceLease);
>>> +                this.serviceLease = 
>>> +                       (Lease)serviceLeasePreparer.prepareProxy(svcLease);
>>>               logger.finest("JoinManager - service lease proxy prepared");
>>>           } catch(Exception e) {
>>> 		LogUtil.logThrow(logger, Level.WARNING, ProxyReg.class,
>>> 		    	"register", "JoinManager - failure during " +
>>> 		    	"preparation of service lease proxy: {0}",
>>> -		    	new Object[] { serviceLease }, e);
>>> +		    	new Object[] { svcLease }, e);
>>>               throw e; //rethrow the exception since proxy may be unusable
>>>           }
>>> -            leaseRenewalMgr.renewUntil(serviceLease, Lease.FOREVER,
>>> +            leaseRenewalMgr.renewUntil(svcLease, Lease.FOREVER,
>>>                                      renewalDuration, dListener);
>>>           ServiceID tmpID = null;
>>>           synchronized(joinSet) {
>>> @@ -1272,7 +1280,11 @@
>>>        *  addition to that service's current set of attributes.
>>>        */
>>>       public void addAttributes(Entry[] attSet) throws Exception {
>>> -            srvcRegistration.addAttributes(attSet);
>>> +            ServiceRegistration sr;
>>> +            synchronized (joinSet){
>>> +                sr = srvcRegistration;
>>> +            }
>>> +            sr.addAttributes(attSet);
>>> 	}//end ProxyReg.addAttributes
>>> 
>>>       /** With respect to the lookup service referenced in this class
>>> @@ -1285,7 +1297,11 @@
>>>       public void modifyAttributes(Entry[] templ, Entry[] attSet)
>>>                                                            throws Exception
>>>       {
>>> -            srvcRegistration.modifyAttributes(templ, attSet);
>>> +            ServiceRegistration sr;
>>> +            synchronized (joinSet){
>>> +               sr = srvcRegistration;
>>> +            }
>>> +            sr.modifyAttributes(templ, attSet);
>>> 	}//end ProxyReg.modifyAttributes		    
>>> 
>>>       /** With respect to the lookup service referenced in this class
>>> @@ -1294,7 +1310,11 @@
>>>        *  set of attributes.
>>>        */
>>>       public void setAttributes(Entry[] attSet) throws Exception {
>>> -            srvcRegistration.setAttributes(attSet);
>>> +            ServiceRegistration sr;
>>> +            synchronized (joinSet){
>>> +               sr = srvcRegistration;
>>> +            }
>>> +            sr.setAttributes(attSet);
>>> 	}//end ProxyReg.setAttributes
>>> 
>>>       /** Convenience method that encapsulates appropriate behavior when
>>> @@ -1432,7 +1452,7 @@
>>>    *  which each task is associated). This field contains the value of
>>>    *  the sequence number assigned to the most recently created task.
>>>    */
>>> -    private int taskSeqN = 0;
>>> +    private int taskSeqN = 0; // access sync on taskList
>>>   /** Task manager for the various tasks executed by this join manager.
>>>    *  On the first attempt to execute any task is managed by this
>>>    *  <code>TaskManager</code> so that the number of concurrent threads
>>> @@ -1442,9 +1462,9 @@
>>>    *  "backoff strategy") - the re-execution of each failed task in this
>>>    *  <code>TaskManager</code>.
>>>    */
>>> -    private TaskManager taskMgr;
>>> +    private final TaskManager taskMgr;
>>>   /** Maximum number of times a failed task is allowed to be re-executed. */
>>> -    private int maxNRetries = 6;
>>> +    private final int maxNRetries;
>>>   /** Wakeup manager for the various tasks executed by this join manager.
>>>    *  After an initial failure of any task executed by this join manager,
>>>    *  the failed task is managed by this <code>WakeupManager</code>; which
>>> @@ -1456,22 +1476,22 @@
>>>    *  join manager is requested, all tasks scheduled for retry by this
>>>    *  wakeup manager can be cancelled.
>>>    */
>>> -    private WakeupManager wakeupMgr;
>>> +    private final WakeupManager wakeupMgr;
>>>   /** Contains the reference to the service that is to be registered with
>>>    *  all of the desired lookup services referenced by <code>discMgr</code>.
>>>    */
>>> -    private ServiceItem serviceItem;
>>> +    private final ServiceItem serviceItem;
>>>   /** Contains the attributes with which to associate the service in each
>>>    *  of the lookup services with which this join manager registers the
>>>    *  service.
>>>    */
>>> -    private Entry[] lookupAttr = null;
>>> +    private Entry[] lookupAttr = null; // access sync on joinSet
>>>   /** Contains the listener -- instantiated by the entity that constructs
>>>    *  this join manager -- that will receive an event containing the
>>>    *  service ID assigned to this join manager's service by one of the
>>>    *  lookup services with which that service is registered.
>>>    */
>>> -    private ServiceIDListener callback;
>>> +    private final ServiceIDListener callback;
>>>   /** Contains elements of type <code>ProxyReg</code> where each element
>>>    *  references a proxy to one of the lookup services with which this
>>>    *  join manager's service is registered.
>>> @@ -1480,22 +1500,22 @@
>>>   /** Contains the discovery manager that discovers the lookup services
>>>    *  with which this join manager will register its associated service.
>>>    */
>>> -    private DiscoveryManagement discMgr = null;
>>> +    private final DiscoveryManagement discMgr;
>>>   /** Contains the discovery listener registered by this join manager with
>>>    *  the discovery manager so that this join manager is notified whenever
>>>    *  one of the desired lookup services is discovered or discarded.
>>>    */
>>> -    private DiscMgrListener discMgrListener = new DiscMgrListener();
>>> +    private final DiscMgrListener discMgrListener ;
>>>   /** Flag that indicate whether the discovery manager employed by this
>>>    *  join manager was created by this join manager itself, or by the
>>>    *  entity that constructed this join manager.
>>>    */
>>> -    private boolean bCreateDiscMgr = false;
>>> +    private final boolean bCreateDiscMgr;
>>>   /** Contains the lease renewal manager that renews all of the leases
>>>    *  this join manager's service holds with each lookup service with which
>>>    *  it has been registered.
>>>    */
>>> -    private LeaseRenewalManager leaseRenewalMgr = null;
>>> +    private final LeaseRenewalManager leaseRenewalMgr;
>>>   /** The value to use as the <code>renewDuration</code> parameter
>>>    *  when invoking the lease renewal manager's <code>renewUntil</code>
>>>    *  method to add a service lease to manage. This value represents,
>>> @@ -1505,22 +1525,22 @@
>>>    *  is up, and lease expirations will occur sooner when the service
>>>    *  goes down.
>>>    */
>>> -    private long renewalDuration = Lease.FOREVER;
>>> +    private final long renewalDuration;
>>>   /** Flag that indicates if this join manager has been terminated. */
>>> -    private volatile boolean bTerminated = false;
>>> +    private boolean bTerminated = false; // All access sync on this.
>>>   /* Preparer for the proxies to the lookup services that are discovered
>>>    * and used by this utility.
>>>    */
>>> -    private ProxyPreparer registrarPreparer;
>>> +    private final ProxyPreparer registrarPreparer;
>>>   /* Preparer for the proxies to the registrations returned to this utility
>>>    * upon registering the service with each discovered lookup service.
>>>    */
>>> -    private ProxyPreparer registrationPreparer;
>>> +    private final ProxyPreparer registrationPreparer;
>>>   /* Preparer for the proxies to the leases returned to this utility through
>>>    * the registrations with each discovered lookup service with which this
>>>    * utility has registered the service.
>>>    */
>>> -    private ProxyPreparer serviceLeasePreparer;
>>> +    private final ProxyPreparer serviceLeasePreparer;
>>> 
>>>   /** 
>>>    * Constructs an instance of this class that will register the given
>>> @@ -1619,11 +1639,8 @@
>>> 			DiscoveryManagement discoveryMgr,
>>> 			LeaseRenewalManager leaseMgr)    throws IOException
>>>   {
>>> -        discMgr = discoveryMgr;
>>> -        try {
>>> -           createJoinManager(null, serviceProxy, attrSets, callback, leaseMgr,
>>> -                             EmptyConfiguration.INSTANCE);
>>> -        } catch(ConfigurationException e) { /* swallow this exception */ }
>>> +           this(serviceProxy, attrSets, null, callback, 
>>> +                 getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy));
>>>   }//end constructor
>>> 
>>>   /** 
>>> @@ -1737,9 +1754,10 @@
>>>                       Configuration config)
>>>                                   throws IOException, ConfigurationException
>>>   {
>>> -        discMgr = discoveryMgr;
>>> -        createJoinManager(null, serviceProxy, attrSets,
>>> -                          callback, leaseMgr, config);
>>> +        
>>> +        this(serviceProxy, attrSets, null, callback, 
>>> +            getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
>>> +        );
>>>   }//end constructor
>>> 
>>>   /** 
>>> @@ -1797,12 +1815,9 @@
>>> 			DiscoveryManagement discoveryMgr,
>>> 			LeaseRenewalManager leaseMgr)    throws IOException
>>>   {
>>> -        discMgr = discoveryMgr;
>>> -        try {
>>> -           createJoinManager(serviceID, serviceProxy, attrSets,
>>> -                             (ServiceIDListener)null, leaseMgr,
>>> -                             EmptyConfiguration.INSTANCE);
>>> -        } catch(ConfigurationException e) { /* swallow this exception */ }
>>> +       this(serviceProxy, attrSets, serviceID, null, 
>>> +             getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy)
>>> +       );
>>>   }//end constructor
>>> 
>>>   /** 
>>> @@ -1877,9 +1892,9 @@
>>>                       Configuration config)
>>>                                   throws IOException, ConfigurationException
>>>   {
>>> -        discMgr = discoveryMgr;
>>> -        createJoinManager(serviceID, serviceProxy, attrSets,
>>> -                          (ServiceIDListener)null, leaseMgr, config);
>>> +        this(serviceProxy, attrSets, serviceID, null, 
>>> +             getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
>>> +       );
>>>   }//end constructor
>>> 
>>>   /** 
>>> @@ -2464,44 +2479,113 @@
>>>       replaceRegistrationDo(serviceProxy, attrSets, true);
>>>   }//end replaceRegistration
>>> 
>>> -    /** Convenience method invoked by the constructors of this class that
>>> -     *  uses the given <code>Configuration</code> to initialize the current
>>> -     *  instance of this utility, and initiates all join processing for
>>> -     *  the given parameters. This method handles the various configurations
>>> -     *  allowed by the different constructors.
>>> +    private static class Conf{
>>> +        ProxyPreparer registrarPreparer;
>>> +        ProxyPreparer registrationPreparer;
>>> +        ProxyPreparer serviceLeasePreparer;
>>> +        TaskManager taskManager;
>>> +        WakeupManager wakeupManager;
>>> +        Integer maxNretrys;
>>> +        LeaseRenewalManager leaseRenewalManager;
>>> +        Long renewalDuration;
>>> +        DiscoveryManagement discoveryMgr;
>>> +        boolean bcreateDisco;
>>> +        
>>> +        Conf (  ProxyPreparer registrarPreparer,
>>> +                ProxyPreparer registrationPreparer,
>>> +                ProxyPreparer serviceLeasePreparer,
>>> +                TaskManager taskManager,
>>> +                WakeupManager wakeupManager,
>>> +                Integer maxNretrys,
>>> +                LeaseRenewalManager leaseRenewalManager,
>>> +                Long renewalDuration,
>>> +                DiscoveryManagement discoveryMgr,
>>> +                boolean bcreateDisco)
>>> +        {
>>> +            this.registrarPreparer = registrarPreparer;
>>> +            this.registrationPreparer = registrationPreparer;
>>> +            this.serviceLeasePreparer = serviceLeasePreparer;
>>> +            this.taskManager = taskManager;
>>> +            this.wakeupManager = wakeupManager;
>>> +            this.maxNretrys = maxNretrys;
>>> +            this.leaseRenewalManager = leaseRenewalManager;
>>> +            this.renewalDuration = renewalDuration;
>>> +            this.discoveryMgr = discoveryMgr;
>>> +            this.bcreateDisco = bcreateDisco;
>>> +        }
>>> +    }
>>> +    
>>> +    /**
>>> +     * This method is for constructors that use an empty configuration.
>>> +     * 
>>> +     * @param config
>>> +     * @param leaseMgr
>>> +     * @param discoveryMgr
>>> +     * @param serviceProxy
>>> +     * @return
>>> +     * @throws IOException
>>> +     * @throws NullPointerException
>>> +     * @throws IllegalArgumentException 
>>>    */
>>> -    private void createJoinManager(ServiceID serviceID, 
>>> -                                   Object serviceProxy,
>>> -                                   Entry[] attrSets, 
>>> -                                   ServiceIDListener callback,
>>> +    private static Conf getConf(    Configuration config,
>>>                                  LeaseRenewalManager leaseMgr,
>>> -                                   Configuration config) 
>>> -                                    throws IOException, ConfigurationException
>>> +                                    DiscoveryManagement discoveryMgr,
>>> +                                    Object serviceProxy) 
>>> +            throws IOException, NullPointerException, IllegalArgumentException {
>>> +        try {
>>> +            return getConfig(config, leaseMgr, discoveryMgr, serviceProxy);
>>> +        } catch (ConfigurationException e){
>>> +            throw new IOException("Configuration problem during construction", e);
>>> +        }
>>> +    }
>>> +    
>>> +    /**
>>> +     * Gets the configuration and throws any exceptions.
>>> +     * 
>>> +     * This static method guards against finalizer attacks and allows fields
>>> +     * to be final.
>>> +     * 
>>> +     * @param config
>>> +     * @param leaseMgr
>>> +     * @param discoveryMgr
>>> +     * @param serviceProxy
>>> +     * @return
>>> +     * @throws IOException
>>> +     * @throws ConfigurationException
>>> +     * @throws NullPointerException
>>> +     * @throws IllegalArgumentException 
>>> +     */
>>> +    private static Conf getConfig(  Configuration config,
>>> +                                    LeaseRenewalManager leaseMgr, 
>>> +                                    DiscoveryManagement discoveryMgr,
>>> +                                    Object serviceProxy) 
>>> +            throws IOException, ConfigurationException, NullPointerException,
>>> +            IllegalArgumentException 
>>>   {
>>> 	if(!(serviceProxy instanceof java.io.Serializable)) {
>>>           throw new IllegalArgumentException
>>>                                      ("serviceProxy must be Serializable");
>>> 	}//endif
>>> -
>>>       /* Retrieve configuration items if applicable */
>>>       if(config == null)  throw new NullPointerException("config is null");
>>>       /* Proxy preparers */
>>> -        registrarPreparer = (ProxyPreparer)config.getEntry
>>> +        ProxyPreparer registrarPreparer = (ProxyPreparer)config.getEntry
>>>                                                  (COMPONENT_NAME,
>>>                                                   "registrarPreparer",
>>>                                                   ProxyPreparer.class,
>>>                                                   new BasicProxyPreparer());
>>> -        registrationPreparer = (ProxyPreparer)config.getEntry
>>> +        ProxyPreparer registrationPreparer = (ProxyPreparer)config.getEntry
>>>                                                  (COMPONENT_NAME,
>>>                                                   "registrationPreparer",
>>>                                                   ProxyPreparer.class,
>>>                                                   new BasicProxyPreparer());
>>> -        serviceLeasePreparer = (ProxyPreparer)config.getEntry
>>> +        ProxyPreparer serviceLeasePreparer = (ProxyPreparer)config.getEntry
>>>                                                  (COMPONENT_NAME,
>>>                                                   "serviceLeasePreparer",
>>>                                                   ProxyPreparer.class,
>>>                                                   new BasicProxyPreparer());
>>>       /* Task manager */
>>> +        TaskManager taskMgr;
>>>       try {
>>>           taskMgr = (TaskManager)config.getEntry(COMPONENT_NAME,
>>>                                                  "taskManager",
>>> @@ -2510,6 +2594,7 @@
>>>           taskMgr = new TaskManager(MAX_N_TASKS,(15*1000),1.0f);
>>>       }
>>>       /* Wakeup manager */
>>> +        WakeupManager wakeupMgr;
>>>       try {
>>>           wakeupMgr = (WakeupManager)config.getEntry(COMPONENT_NAME,
>>>                                                      "wakeupManager",
>>> @@ -2519,57 +2604,84 @@
>>>                                   (new WakeupManager.ThreadDesc(null,true));
>>>       }
>>>       /* Max number of times to re-schedule tasks in thru wakeup manager */
>>> -        maxNRetries = ((Integer)config.getEntry
>>> +        Integer maxNRetries = ((Integer)config.getEntry
>>>                                       (COMPONENT_NAME,
>>>                                        "wakeupRetries",
>>>                                        int.class,
>>> -                                         Integer.valueOf(maxNRetries))).intValue();
>>> -        if(attrSets == null) {
>>> -            lookupAttr = new Entry[0];
>>> -        } else {
>>> -            attrSets = (Entry[])attrSets.clone();
>>> -            LookupAttributes.check(attrSets,false);//null elements NOT ok
>>> -            lookupAttr = attrSets;
>>> -        }//endif
>>> -	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
>>> +                                         Integer.valueOf(6))).intValue();
>>>       /* Lease renewal manager */
>>> -        leaseRenewalMgr = leaseMgr;
>>> -	if(leaseRenewalMgr == null) {
>>> +	if(leaseMgr == null) {
>>>           try {
>>> -                leaseRenewalMgr = (LeaseRenewalManager)config.getEntry
>>> +                leaseMgr = (LeaseRenewalManager)config.getEntry
>>>                                                 (COMPONENT_NAME,
>>>                                                  "leaseManager",
>>>                                                  LeaseRenewalManager.class);
>>>           } catch(NoSuchEntryException e) { /* use default */
>>> -                leaseRenewalMgr = new LeaseRenewalManager(config);
>>> +                leaseMgr = new LeaseRenewalManager(config);
>>>           }
>>>       }//endif
>>> -        renewalDuration = ((Long)config.getEntry
>>> +        Long renewalDuration = ((Long)config.getEntry
>>>                                     (COMPONENT_NAME,
>>>                                      "maxLeaseDuration",
>>>                                      long.class,
>>> -                                       Long.valueOf(renewalDuration))).longValue();
>>> +                                       Long.valueOf(Lease.FOREVER))).longValue();
>>>       if( (renewalDuration == 0) || (renewalDuration < Lease.ANY) ) {
>>>           throw new ConfigurationException("invalid configuration entry: "
>>>                                            +"renewalDuration ("
>>>                                            +renewalDuration+") must be "
>>>                                            +"positive or Lease.ANY");
>>>       }//endif
>>> -	this.callback = callback;
>>>       /* Discovery manager */
>>> -	if(discMgr == null) {
>>> +        boolean bCreateDiscMgr = false;
>>> +	if(discoveryMgr == null) {
>>> 	    bCreateDiscMgr = true;
>>>           try {
>>> -                discMgr = (DiscoveryManagement)config.getEntry
>>> +                discoveryMgr = (DiscoveryManagement)config.getEntry
>>>                                                (COMPONENT_NAME,
>>>                                                 "discoveryManager",
>>>                                                 DiscoveryManagement.class);
>>>           } catch(NoSuchEntryException e) { /* use default */
>>> -                discMgr = new LookupDiscoveryManager
>>> +                discoveryMgr = new LookupDiscoveryManager
>>>                                    (new String[] {""}, null, null, config);
>>>           }
>>> 	}//endif
>>> -	discMgr.addDiscoveryListener(discMgrListener);
>>> +        return new Conf(registrarPreparer, registrationPreparer, serviceLeasePreparer,
>>> +                taskMgr, wakeupMgr, maxNRetries, leaseMgr, renewalDuration,
>>> +                discoveryMgr, bCreateDiscMgr);
>>> +    }
>>> +    
>>> +    /** Convenience method invoked by the constructors of this class that
>>> +     *  uses the given <code>Configuration</code> to initialize the current
>>> +     *  instance of this utility, and initiates all join processing for
>>> +     *  the given parameters. This method handles the various configurations
>>> +     *  allowed by the different constructors.
>>> +     */
>>> +    private JoinManager(Object serviceProxy,
>>> +                                   Entry[] attrSets, ServiceID serviceID, 
>>> +                                   ServiceIDListener callback, Conf conf)
>>> +    {
>>> +	registrarPreparer = conf.registrarPreparer;
>>> +        registrationPreparer = conf.registrationPreparer;
>>> +        serviceLeasePreparer = conf.serviceLeasePreparer;
>>> +        taskMgr = conf.taskManager;
>>> +        wakeupMgr = conf.wakeupManager;
>>> +        maxNRetries = conf.maxNretrys;
>>> +        leaseRenewalMgr = conf.leaseRenewalManager;
>>> +        renewalDuration = conf.renewalDuration;
>>> +        bCreateDiscMgr = conf.bcreateDisco;
>>> +        DiscMgrListener discMgrListen = new DiscMgrListener();
>>> +        if(attrSets == null) {
>>> +            lookupAttr = new Entry[0];
>>> +        } else {
>>> +            attrSets = attrSets.clone();
>>> +            LookupAttributes.check(attrSets,false);//null elements NOT ok
>>> +            lookupAttr = attrSets;
>>> +        }//endif
>>> +	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
>>> +	this.callback = callback;
>>> +	conf.discoveryMgr.addDiscoveryListener(discMgrListen);
>>> +        discMgr = conf.discoveryMgr;
>>> +        discMgrListener = discMgrListen;
>>>   }//end createJoinManager
>>> 
>>>   /** For the given lookup service proxy, searches the <code>joinSet</code>
>>> @@ -2623,9 +2735,10 @@
>>>               }//end loop
>>>               /* Interrupt all active tasks, prepare taskMgr for GC. */
>>>               taskMgr.terminate();
>>> -                taskMgr = null;
>>> +        // Too lazy to put out the trash.
>>> +//                taskMgr = null;
>>>           }//end sync(taskMgr)
>>> -            wakeupMgr = null;
>>> +//            wakeupMgr = null;
>>>       }//end sync(wakeupMgr)
>>>   }//end terminateTaskMgr
>>> 
>>> Index: src/org/apache/river/api/security/URIGrant.java
>>> --- src/org/apache/river/api/security/URIGrant.java Base (BASE)
>>> +++ src/org/apache/river/api/security/URIGrant.java Locally Modified (Based On LOCAL)
>>> @@ -135,12 +135,17 @@
>>>       if (url == null ) return false;
>>>       Uri implied = null;
>>>       try {
>>> -            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
>>> -        } catch (PrivilegedActionException ex) {
>>> -            Exception cause = ex.getException();
>>> -            cause.printStackTrace(System.err);
>>> -            return false;
>>> +            implied = Uri.urlToUri(url);
>>> +        } catch (URISyntaxException ex) {
>>> +            Logger.getLogger(URIGrant.class.getName()).log(Level.SEVERE, null, ex);
>>>       }
>>> +//        try {
>>> +//            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
>>> +//        } catch (PrivilegedActionException ex) {
>>> +//            Exception cause = ex.getException();
>>> +//            cause.printStackTrace(System.err);
>>> +//            return false;
>>> +//        }
>>>       for (int i = 0; i<l ; i++){
>>>           if (uris[i].implies(implied)) return true;
>>>       }
>> 
> 


Re: Indefinite hang - no progress while in loop liveness failure

Posted by Gregg Wonderly <gr...@wonderly.org>.
Let me be more specific.  There are many "logic elimination" optimizations in the hit these days.  For non-volatile and unsynchronized access to "class variables", the JIT will make the assessment that because you don't both read and write the variable in the method, that the value will never change, and thus it will read it only once, and do some things such as loop test hoisting.  I haven't had a chance yet to see what code this method generates, but I would almost bet, that something happens in here that eliminates the tests.

Gregg

On Apr 14, 2013, at 7:53 PM, Gregg Wonderly <ge...@cox.net> wrote:

> Because pending is accessed in that method (isCompleted), and it is non-volatile, and the method is not synchronized, all bets are off on predictable behavior.
> 
> Gregg Wonderly
> 
> On Apr 14, 2013, at 3:16 PM, Peter Firmstone <ji...@zeus.net.au> wrote:
> 
>> Gregg,
>> 
>> You are so right, I've just spent the weekend trying to fix an unrelated test, fixing one problem reveals another.
>> 
>> The patch (attached) attempts to fix some synchronization issues with Mahalo, this patch needs to be applied against qa-refactoring in skunk.
>> 
>> These two tests hang indefinitely:
>> 
>> com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
>> 
>> com.sun.jini.test.impl.mahalo.PrepareAndCommitExceptionTest4.td  (Thread dump for this test appended).
>> 
>> 2013-04-15 05:53:48
>> Full thread dump Java HotSpot(TM) Server VM (20.5-b03 mixed mode):
>> 
>> "RMI TCP Connection(332)-10.1.1.2" daemon prio=3 tid=0x007fd800 nid=0x6a runnable [0xb517f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.SocketInputStream.socketRead0(Native Method)
>>  at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>  at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>>  at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>>  - locked <0xe66ec2e0> (a java.io.BufferedInputStream)
>>  at java.io.FilterInputStream.read(FilterInputStream.java:66)
>>  at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>>  at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>>  at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>>  at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - <0xe645f1d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
>> 
>> "(JSK) mux request dispatch" daemon prio=3 tid=0x01013000 nid=0x33 runnable [0xb467d000]
>> java.lang.Thread.State: RUNNABLE
>>  at com.sun.jini.mahalo.AbortJob.computeResult(AbortJob.java:284)
>>  - locked <0xbb8a2c10> (a com.sun.jini.mahalo.AbortJob)
>>  at com.sun.jini.mahalo.TxnManagerTransaction.abort(TxnManagerTransaction.java:1034)
>>  - locked <0xbb8a2c60> (a java.lang.Object)
>>  at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:795)
>>  at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:754)
>>  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>  at java.lang.reflect.Method.invoke(Method.java:597)
>>  at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>>  at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>>  at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>>  at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>>  at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>>  at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>>  at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>>  at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>>  at java.security.AccessController.doPrivileged(Native Method)
>>  at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>>  at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>>  at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>>  at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>>  at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>>  at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>>  at java.security.AccessController.doPrivileged(Native Method)
>>  at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) mux reader" daemon prio=3 tid=0x01011400 nid=0x32 runnable [0xb477f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.SocketInputStream.socketRead0(Native Method)
>>  at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) mux reader" daemon prio=3 tid=0x005b0400 nid=0x31 runnable [0xb487f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.SocketInputStream.socketRead0(Native Method)
>>  at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) mux writer" daemon prio=3 tid=0x005af400 nid=0x30 in Object.wait() [0xb497f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8a6d20> (a java.lang.Object)
>>  at java.lang.Object.wait(Object.java:485)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>  - locked <0xbb8a6d20> (a java.lang.Object)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) mux writer" daemon prio=3 tid=0x005ae000 nid=0x2f in Object.wait() [0xb4a7f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8aad00> (a java.lang.Object)
>>  at java.lang.Object.wait(Object.java:485)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>  - locked <0xbb8aad00> (a java.lang.Object)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) ConnectionManager.Reaper" daemon prio=3 tid=0x007ff000 nid=0x2c waiting on condition [0xb4d7f000]
>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>  at java.lang.Thread.sleep(Native Method)
>>  at net.jini.jeri.connection.ConnectionManager$Reaper.run(ConnectionManager.java:597)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) mux request dispatch" daemon prio=3 tid=0x006a0800 nid=0x2a in Object.wait() [0xb4f7d000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8aaf10> (a java.lang.Object)
>>  at java.lang.Object.wait(Object.java:485)
>>  at com.sun.jini.jeri.internal.mux.Session$MuxInputStream.read(Session.java:853)
>>  - locked <0xbb8aaf10> (a java.lang.Object)
>>  at net.jini.jeri.connection.ConnectionManager$Outbound$Input.read(ConnectionManager.java:550)
>>  at net.jini.jeri.BasicObjectEndpoint.executeCall(BasicObjectEndpoint.java:410)
>>  at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:806)
>>  at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
>>  at net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
>>  at $Proxy0.abort(Unknown Source)
>>  at com.sun.jini.mahalo.TxnMgrProxy.abort(TxnMgrProxy.java:146)
>>  at net.jini.core.transaction.server.ServerTransaction.abort(ServerTransaction.java:113)
>>  at com.sun.jini.mahalo.TxnManagerTransaction.doAbort(TxnManagerTransaction.java:1134)
>>  at com.sun.jini.mahalo.TxnManagerTransaction.commit(TxnManagerTransaction.java:763)
>>  at com.sun.jini.mahalo.TxnManagerImpl.commit(TxnManagerImpl.java:712)
>>  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>  at java.lang.reflect.Method.invoke(Method.java:597)
>>  at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>>  at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>>  at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>>  at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>>  at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>>  at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>>  at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>>  at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>>  at java.security.AccessController.doPrivileged(Native Method)
>>  at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>>  at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>>  at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>>  at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>>  at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>>  at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>>  at java.security.AccessController.doPrivileged(Native Method)
>>  at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) mux reader" daemon prio=3 tid=0x003bfc00 nid=0x26 runnable [0xb537f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.SocketInputStream.socketRead0(Native Method)
>>  at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) mux writer" daemon prio=3 tid=0x00984400 nid=0x25 in Object.wait() [0xb547f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8bad70> (a java.lang.Object)
>>  at java.lang.Object.wait(Object.java:485)
>>  at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>>  - locked <0xbb8bad70> (a java.lang.Object)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "event listener notification" daemon prio=3 tid=0x00483000 nid=0x23 in Object.wait() [0xb567f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8bb778> (a java.util.LinkedList)
>>  at java.lang.Object.wait(Object.java:485)
>>  at net.jini.discovery.LookupDiscovery$Notifier.run(LookupDiscovery.java:920)
>>  - locked <0xbb8bb778> (a java.util.LinkedList)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "multicast announcement timer" daemon prio=3 tid=0x00ade000 nid=0x22 waiting on condition [0xb577f000]
>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>  at java.lang.Thread.sleep(Native Method)
>>  at net.jini.discovery.LookupDiscovery$AnnouncementTimerThread.run(LookupDiscovery.java:1434)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "multicast discovery announcement listener" daemon prio=3 tid=0x00adcc00 nid=0x21 runnable [0xb587f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.PlainDatagramSocketImpl.peekData(Native Method)
>>  - locked <0xbb8bdab8> (a java.net.PlainDatagramSocketImpl)
>>  at java.net.DatagramSocket.receive(DatagramSocket.java:675)
>>  - locked <0xbb8bfae8> (a java.net.DatagramPacket)
>>  - locked <0xbb8bda80> (a java.net.MulticastSocket)
>>  at net.jini.discovery.LookupDiscovery$AnnouncementListener.run(LookupDiscovery.java:1205)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "settleThread" daemon prio=3 tid=0x00669c00 nid=0x1e in Object.wait() [0xb5b7f000]
>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
>>  at com.sun.jini.mahalo.TxnManagerImpl.settleTxns(TxnManagerImpl.java:885)
>>  - locked <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
>>  at com.sun.jini.mahalo.TxnManagerImpl.access$100(TxnManagerImpl.java:117)
>>  at com.sun.jini.mahalo.TxnManagerImpl$2.run(TxnManagerImpl.java:331)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) KeepAlive" prio=3 tid=0x005cc800 nid=0x1d waiting on condition [0xb5c7f000]
>> java.lang.Thread.State: TIMED_WAITING (sleeping)
>>  at java.lang.Thread.sleep(Native Method)
>>  at com.sun.jini.jeri.internal.runtime.JvmLifeSupport$2.run(JvmLifeSupport.java:133)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) Reaper" daemon prio=3 tid=0x005cc000 nid=0x1c in Object.wait() [0xb5d7f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
>>  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>  - locked <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
>>  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>  at com.sun.jini.jeri.internal.runtime.ImplRefManager$Reaper.run(ImplRefManager.java:426)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "(JSK) TcpServerEndpoint.LH[ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=36713]] accept loop" daemon prio=3 tid=0x005ce400 nid=0x1b runnable [0xb5e7f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.PlainSocketImpl.socketAccept(Native Method)
>>  at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>  - locked <0xbb8b8708> (a java.net.SocksSocketImpl)
>>  at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>  at java.net.ServerSocket.accept(ServerSocket.java:430)
>>  at net.jini.jeri.tcp.TcpServerEndpoint$LH.executeAcceptLoop(TcpServerEndpoint.java:797)
>>  at net.jini.jeri.tcp.TcpServerEndpoint$LH.access$400(TcpServerEndpoint.java:735)
>>  at net.jini.jeri.tcp.TcpServerEndpoint$LH$1.run(TcpServerEndpoint.java:767)
>>  at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>>  at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "RMI TCP Connection(331)-10.1.1.2" daemon prio=3 tid=0x003a8c00 nid=0x1a runnable [0xb5f7f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.SocketInputStream.socketRead0(Native Method)
>>  at java.net.SocketInputStream.read(SocketInputStream.java:129)
>>  at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>>  at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>>  - locked <0xe66b5280> (a java.io.BufferedInputStream)
>>  at java.io.FilterInputStream.read(FilterInputStream.java:66)
>>  at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>>  at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>>  at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>>  at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - <0xbb8c0420> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
>> 
>> "JMX server connection timeout 18" daemon prio=3 tid=0x005cf800 nid=0x19 in Object.wait() [0xb607f000]
>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8c0718> (a [I)
>>  at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150)
>>  - locked <0xbb8c0718> (a [I)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "RMI Scheduler(0)" daemon prio=3 tid=0x005d1400 nid=0x18 waiting on condition [0xb617f000]
>> java.lang.Thread.State: TIMED_WAITING (parking)
>>  at sun.misc.Unsafe.park(Native Method)
>>  - parking to wait for  <0xbb8a2178> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>>  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>>  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>>  at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>>  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>>  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>>  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>>  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "DestroyJavaVM" prio=3 tid=0x00031800 nid=0x2 waiting on condition [0x00000000]
>> java.lang.Thread.State: RUNNABLE
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "Thread-1" prio=3 tid=0x004be800 nid=0x17 runnable [0xb627f000]
>> java.lang.Thread.State: TIMED_WAITING (parking)
>>  at sun.misc.Unsafe.park(Native Method)
>>  - parking to wait for  <0xbb8c0cd0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>>  at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>>  at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>>  at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>>  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>>  at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>>  at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>>  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "GC Daemon" daemon prio=3 tid=0x0052dc00 nid=0x15 in Object.wait() [0xb647f000]
>> java.lang.Thread.State: TIMED_WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb8076b8> (a sun.misc.GC$LatencyLock)
>>  at sun.misc.GC$Daemon.run(GC.java:100)
>>  - locked <0xbb8076b8> (a sun.misc.GC$LatencyLock)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "RMI Reaper" prio=3 tid=0x00529800 nid=0x14 in Object.wait() [0xb657f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
>>  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>  - locked <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
>>  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>  at sun.rmi.transport.ObjectTable$Reaper.run(ObjectTable.java:333)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "RMI TCP Accept-0" daemon prio=3 tid=0x002f5400 nid=0x13 runnable [0xb667f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.PlainSocketImpl.socketAccept(Native Method)
>>  at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>  - locked <0xbb8001a8> (a java.net.SocksSocketImpl)
>>  at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>  at java.net.ServerSocket.accept(ServerSocket.java:430)
>>  at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>>  at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "RMI TCP Accept-0" daemon prio=3 tid=0x002f4c00 nid=0x12 runnable [0xb677f000]
>> java.lang.Thread.State: RUNNABLE
>>  at java.net.PlainSocketImpl.socketAccept(Native Method)
>>  at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>>  - locked <0xbb803c98> (a java.net.SocksSocketImpl)
>>  at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>>  at java.net.ServerSocket.accept(ServerSocket.java:430)
>>  at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:34)
>>  at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>>  at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>>  at java.lang.Thread.run(Thread.java:662)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "Attach Listener" daemon prio=3 tid=0x0020ac00 nid=0xf waiting on condition [0x00000000]
>> java.lang.Thread.State: RUNNABLE
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "Low Memory Detector" daemon prio=3 tid=0x00124000 nid=0xd runnable [0x00000000]
>> java.lang.Thread.State: RUNNABLE
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "C2 CompilerThread1" daemon prio=3 tid=0x00121000 nid=0xc waiting on condition [0x00000000]
>> java.lang.Thread.State: RUNNABLE
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "C2 CompilerThread0" daemon prio=3 tid=0x0011ec00 nid=0xb waiting on condition [0x00000000]
>> java.lang.Thread.State: RUNNABLE
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "Signal Dispatcher" daemon prio=3 tid=0x0011d000 nid=0xa runnable [0x00000000]
>> java.lang.Thread.State: RUNNABLE
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "Finalizer" daemon prio=3 tid=0x0010c800 nid=0x9 in Object.wait() [0xb707f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
>>  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>>  - locked <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
>>  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>>  at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "Reference Handler" daemon prio=3 tid=0x00107c00 nid=0x8 in Object.wait() [0xb717f000]
>> java.lang.Thread.State: WAITING (on object monitor)
>>  at java.lang.Object.wait(Native Method)
>>  - waiting on <0xbb804090> (a java.lang.ref.Reference$Lock)
>>  at java.lang.Object.wait(Object.java:485)
>>  at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
>>  - locked <0xbb804090> (a java.lang.ref.Reference$Lock)
>> 
>> Locked ownable synchronizers:
>>  - None
>> 
>> "VM Thread" prio=3 tid=0x00104000 nid=0x7 runnable
>> 
>> "GC task thread#0 (ParallelGC)" prio=3 tid=0x00039000 nid=0x3 runnable
>> 
>> "GC task thread#1 (ParallelGC)" prio=3 tid=0x0003a800 nid=0x4 runnable
>> 
>> "GC task thread#2 (ParallelGC)" prio=3 tid=0x0003bc00 nid=0x5 runnable
>> 
>> "GC task thread#3 (ParallelGC)" prio=3 tid=0x0003d000 nid=0x6 runnable
>> 
>> "VM Periodic Task Thread" prio=3 tid=0x00136000 nid=0xe waiting on condition
>> 
>> JNI global references: 1404
>> 
>> # This patch file was generated by NetBeans IDE
>> # Following Index: paths are relative to: /opt/src/River_Fixed/peterConcurrentPolicy
>> # This patch can be applied using context Tools: Patch action on respective folder.
>> # It uses platform neutral UTF-8 encoding and \n newlines.
>> # Above lines and this line are ignored by the patching process.
>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td
>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Base (BASE)
>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Locally Modified (Based On LOCAL)
>> @@ -1,3 +1,6 @@
>> include0=mahalo.properties
>> testClass=PrepareAndCommitExceptionTest
>> testCategories=txnmanager,txnmanager_impl
>> +#testjvmargs=-Xdebug,\
>> +#-Xrunjdwp:transport=dt_socket+,address=8000+,server=y+,suspend=y,\
>> +#${testjvmargs}
>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java
>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Base (BASE)
>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Locally Modified (Based On LOCAL)
>> @@ -44,15 +44,15 @@
>> */
>> public class PrepareAndCommitExceptionTest2 extends TxnManagerTest {
>> 
>> -      class Clearer implements Runnable {
>> -         TestParticipant part;
>> +      static class Clearer implements Runnable {
>> +         final TestParticipant part;
>>         Clearer(TestParticipant part) {
>>             this.part = part;
>>         }
>> 
>>         public void run() {
>>            try {
>> -                Thread.sleep(10000);
>> +                Thread.sleep(1000); // was 10 minutes, not necessary on modern hardware.
>>            } catch (Exception e) {
>>                logger.log(Level.INFO, "Caught sleep exception -- ignoring: " + e);                                    
>>            }
>> @@ -94,7 +94,7 @@
>>        t.start();
>>        logger.log(Level.INFO, "Committing transaction");                        
>>        try {
>> -            cr.transaction.commit(60000);
>> +            cr.transaction.commit(2000); // Was 60 minutes, didn't feel like waiting that long!
>>            throw new TestException("ServerException not thrown");
>>        } catch (ServerException se) {
>>            logger.log(Level.INFO, "Caught expected exception: " + se);                                    
>> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
>> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Base (BASE)
>> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Locally Modified (Based On LOCAL)
>> @@ -1,3 +1,4 @@
>> include0=mahalo.properties
>> testClass=PrepareAndCommitExceptionTest2
>> testCategories=txnmanager,txnmanager_impl
>> +# This test presently hangs, if the Clearer thread runs after the commit timeout, it doesn't occur.
>> \ No newline at end of file
>> Index: qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java
>> --- qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Base (BASE)
>> +++ qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Locally Modified (Based On LOCAL)
>> @@ -68,11 +68,11 @@
>>    private long sleep_time = SLEEP_TIME;
>> 
>>    // Another values.
>> -    private TransactionManager mgr = null;
>> +    private volatile TransactionManager mgr = null;
>>    private TaskManager threadpool = null;
>> -    private WakeupManager wakeupManager = null;
>> -    private Random random;
>> -    private long seed = 0;
>> +    private volatile WakeupManager wakeupManager = null;
>> +    private volatile Random random;
>> +    private volatile long seed = 0;
>> 
>>    public Test construct(QAConfig sysConfig) throws Exception {
>>        super.construct(sysConfig);
>> Index: qa/src/com/sun/jini/test/share/TestParticipantImpl.java
>> --- qa/src/com/sun/jini/test/share/TestParticipantImpl.java Base (BASE)
>> +++ qa/src/com/sun/jini/test/share/TestParticipantImpl.java Locally Modified (Based On LOCAL)
>> @@ -19,6 +19,8 @@
>> package com.sun.jini.test.share;
>> 
>> import com.sun.jini.mahalo.*;
>> +import java.util.logging.Level;
>> +import java.util.logging.Logger;
>> import net.jini.core.transaction.*;
>> import net.jini.core.transaction.server.*;
>> 
>> @@ -48,15 +50,16 @@
>> 	       TransactionParticipant, TestParticipant, ProxyAccessor,
>> 	       ServerProxyTrust
>> {
>> -    private String name;
>> -    private BitSet behavior; 
>> +    private final String name;
>> +    private final BitSet behavior; 
>>    private final Object lock2;
>> -    private long crashcount;
>> -    private ServerTransaction str;
>> +    private volatile long crashcount; // atomic increment with lock2
>> +    private volatile ServerTransaction str;
>>    private static final long TENSECONDS = 1000 * 10;
>>    private static final long THIRTYSECONDS = TENSECONDS *3;
>>    private static final boolean DEBUG = true;
>> -    private TransactionParticipant proxy;
>> +    private volatile TransactionParticipant proxy = null;
>> +    private Exporter exporter;
>> 
>>    public TestParticipantImpl() throws RemoteException {
>> 	this(DEFAULT_NAME);
>> @@ -68,7 +71,7 @@
>> 	crashcount = System.currentTimeMillis();
>> 	behavior   = new BitSet(OPERATION_COUNT);
>> 	Configuration c = QAConfig.getConfig().getConfiguration();
>> -	Exporter exporter = QAConfig.getDefaultExporter();
>> +	exporter = QAConfig.getDefaultExporter();
>> 	if (c instanceof com.sun.jini.qa.harness.QAConfiguration) {
>> 	    try {
>> 		exporter = (Exporter) c.getEntry("test",
>> @@ -78,15 +81,28 @@
>> 		throw new RemoteException("Configuration Error", e);
>> 	    }
>> 	}
>> -	proxy = (TransactionParticipant)exporter.export(this);
>> +        // Can't export here without this escaping.
>>    }
>> 
>>    public Object getProxy() {
>> +        if (proxy != null){
>> 	return proxy;
>> +        } else {
>> +            synchronized (lock2){
>> +                if (proxy != null) return proxy; // Don't export it twice.
>> +                try {
>> +                    proxy = (TransactionParticipant)exporter.export(this);
>> +                    exporter = null;
>> +                } catch (ExportException ex) {
>> +                    // Nothing we can do
>>    }
>> +            }
>> +        }
>> +        return proxy; // May be null
>> +    }
>> 
>>    public TrustVerifier getProxyVerifier() {
>> -	return new BasicProxyTrustVerifier(proxy);
>> +	return new BasicProxyTrustVerifier(getProxy());
>>    }
>> 
>>    private boolean checkBit(int bit) {
>> @@ -136,7 +152,7 @@
>> 		System.out.println(name + ": joining");
>> 	    }
>> 
>> -	    str.join(proxy, crashcount);
>> +	    str.join((TransactionParticipant) getProxy(), crashcount);
>> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
>> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
>> 		    doTimeout(THIRTYSECONDS);
>> @@ -157,7 +173,7 @@
>> 		System.out.println(name + ": joining again");
>> 	    }
>> 
>> -	    str.join(proxy, crashcount);
>> +	    str.join((TransactionParticipant) getProxy(), crashcount);
>> 
>> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
>> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
>> Index: qa/src/com/sun/jini/test/share/TxnManagerTest.java
>> --- qa/src/com/sun/jini/test/share/TxnManagerTest.java Base (BASE)
>> +++ qa/src/com/sun/jini/test/share/TxnManagerTest.java Locally Modified (Based On LOCAL)
>> @@ -42,16 +42,20 @@
>> {
>>    protected static final boolean DEBUG = true;
>> 
>> -    TransactionManager[] mgrs = new TransactionManager[1];
>> +    final TransactionManager[] mgrs = new TransactionManager[1];
>> 
>>    public TransactionManager manager() throws RemoteException {
>> +        synchronized (mgrs){
>> 	return (TransactionManager) mgrs[0];
>>    }
>> +    }
>> 
>>    protected void startTxnMgr() throws TestException {
>> 	specifyServices(new Class[] {TransactionManager.class}); 
>> +        synchronized (mgrs){
>> 	mgrs[0]= (TransactionManager)services[0]; // prepared by specifyServices
>>    }
>> +    }
>> 
>>    public Test construct(QAConfig config) throws Exception {
>>        super.construct(config);
>> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java
>> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Base (BASE)
>> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Locally Modified (Based On LOCAL)
>> @@ -192,7 +192,9 @@
>>            if (trc == null) {
>>                throw new TestException("Null transaction has been obtained.");
>>            }
>> +            synchronized (txns){
>>            txns.add(trc.transaction);
>> +            }
>>            return trc.transaction;
>>        } catch (Exception e) {
>>            throw new TestException("Could not create transaction.", e);
>> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties
>> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Base (BASE)
>> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Locally Modified (Based On LOCAL)
>> @@ -15,8 +15,8 @@
>> 
>> # timeout2 must be greater than (timeout1 + instantTime)
>> # it is recommended that timeout2 be greater than (timeout1 + 2*instantTime)
>> -com.sun.jini.test.spec.javaspace.conformance.timeout1=24000
>> -com.sun.jini.test.spec.javaspace.conformance.timeout2=48000
>> +com.sun.jini.test.spec.javaspace.conformance.timeout1=20000
>> +com.sun.jini.test.spec.javaspace.conformance.timeout2=40000
>> 
>> #  general round trip time expected to non-blocking operations.
>> #  should be set to checkTime / 2. 
>> Index: qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java
>> --- qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Base (BASE)
>> +++ qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Locally Modified (Based On LOCAL)
>> @@ -80,11 +80,11 @@
>>            while (true) {
>>                state = str.mgr.getState(str.id);
>> 
>> -                if (DEBUG) {
>> -                    int st = state;
>> -                    logger.log(Level.INFO, "state = "
>> -                            + com.sun.jini.constants.TxnConstants.getName(st));
>> -                }
>> +//                if (DEBUG) {
>> +//                    int st = state;
>> +//                    logger.log(Level.FINEST, "state = "
>> +//                            + com.sun.jini.constants.TxnConstants.getName(st));
>> +//                }
>> 
>>                if (state == COMMITTED) {
>>                    break;
>> Index: qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java
>> --- qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Base (BASE)
>> +++ qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Locally Modified (Based On LOCAL)
>> @@ -21,15 +21,16 @@
>> 
>> 
>> class CommitThread extends Thread {
>> -    long timeOut;
>> -    Transaction tr;
>> +    final long timeOut;
>> +    final Transaction tr;
>> 
>>    public CommitThread(Transaction tr) {
>>        this.tr = tr;
>> +        timeOut = 0;
>>    }
>> 
>>    public CommitThread(Transaction tr, long timeOut) {
>> -        this(tr);
>> +        this.tr = tr;
>> 
>>        if (timeOut < 0) {
>>            throw new IllegalArgumentException("timeout must be non-negative");
>> Index: src/com/sun/jini/collection/WeakTable.java
>> --- src/com/sun/jini/collection/WeakTable.java Base (BASE)
>> +++ src/com/sun/jini/collection/WeakTable.java Locally Modified (Based On LOCAL)
>> @@ -52,16 +52,16 @@
>> */
>> public class WeakTable {
>>    /** The map of known objects.  */
>> -    private HashMap		table = new HashMap();
>> +    private final HashMap table;
>> 
>>    /** The queue of cleared SpaceProxy objects. */
>> -    private ReferenceQueue	refQueue = new ReferenceQueue();
>> +    private final ReferenceQueue refQueue;
>> 
>>    /** Print debug messages to this stream if not <code>null</code>. */
>>    private static PrintStream		DEBUG = null;
>> 
>>    /** Object to call back when keys are collected */
>> -    private KeyGCHandler handler = null;
>> +    private final KeyGCHandler handler;
>> 
>>    /**
>>     * Create a new WeakTable object to maintain the maps.
>> @@ -72,6 +72,7 @@
>> 
>> 	table = new HashMap();
>> 	refQueue = new ReferenceQueue();
>> +        handler = null;
>>    }
>> 
>>    /**
>> @@ -79,7 +80,11 @@
>>     * back the designated object when keys are collected.
>>     */
>>    public WeakTable(KeyGCHandler handler) {
>> -	this();
>> +        if (DEBUG != null)
>> +	    DEBUG.println("Creating WeakTable");
>> +
>> +	table = new HashMap();
>> +	refQueue = new ReferenceQueue();
>> 	this.handler = handler;
>>    }
>> 
>> Index: src/com/sun/jini/mahalo/AbortJob.java
>> --- src/com/sun/jini/mahalo/AbortJob.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/AbortJob.java Locally Modified (Based On LOCAL)
>> @@ -29,6 +29,7 @@
>> import java.rmi.ConnectIOException;
>> import java.rmi.AccessException;
>> import java.rmi.ConnectException;
>> +import java.util.Iterator;
>> 
>> import java.util.logging.Level;
>> import java.util.logging.Logger;
>> @@ -54,10 +55,10 @@
>> *
>> */
>> public class AbortJob extends Job implements TransactionConstants {
>> -    ServerTransaction tr;
>> -    ClientLog log;
>> -    ParticipantHandle[] handles;
>> -    int maxtries = 5;
>> +    final ServerTransaction tr;
>> +    final ClientLog log;
>> +    final ParticipantHandle[] handles;
>> +    final int maxtries = 5;
>>    static final Logger logger = TxnManagerImpl.participantLogger;
>> 
>>    /**
>> @@ -272,13 +273,16 @@
>> 	int tmp = 0;
>> 	int count = 0;
>> 
>> -	checkresults:
>> -	for (int i = 0; i < results.length; i++) {
>> -	    tmp = ((Integer)results[i]).intValue();
>> -
>> -	    if (tmp == ABORTED)
>> -		count++;
>> +        synchronized (this){
>> +            Iterator i = results.values().iterator();
>> +            while (i.hasNext()){
>> +                Object res = i.hasNext();
>> +                if (res instanceof Integer){
>> +                    tmp = ((Integer)res).intValue();
>> +                    if (tmp == ABORTED) count++;
>> 	}
>> +            }
>> +        }
>> 
>>        if (logger.isLoggable(Level.FINEST)) {
>>            logger.log(Level.FINEST,
>> Index: src/com/sun/jini/mahalo/AbortRecord.java
>> --- src/com/sun/jini/mahalo/AbortRecord.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/AbortRecord.java Locally Modified (Based On LOCAL)
>> @@ -33,7 +33,7 @@
>>    /**
>>     * @serial
>>     */
>> -    private ParticipantHandle[] parts;
>> +    private final ParticipantHandle[] parts;
>> 
>>    static final long serialVersionUID = -8121722031382234695L;
>> 
>> Index: src/com/sun/jini/mahalo/CommitJob.java
>> --- src/com/sun/jini/mahalo/CommitJob.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/CommitJob.java Locally Modified (Based On LOCAL)
>> @@ -29,6 +29,7 @@
>> import java.rmi.ConnectIOException;
>> import java.rmi.AccessException;
>> import java.rmi.ConnectException;
>> +import java.util.Iterator;
>> 
>> import java.util.logging.Level;
>> import java.util.logging.Logger;
>> @@ -51,10 +52,10 @@
>> * @see net.jini.core.transaction.server.TransactionParticipant
>> */
>> public class CommitJob extends Job implements TransactionConstants {
>> -    ServerTransaction tr;
>> -    ClientLog log;
>> -    ParticipantHandle[] handles;
>> -    int maxtries = Integer.MAX_VALUE;
>> +    final ServerTransaction tr;
>> +    final ClientLog log;
>> +    final ParticipantHandle[] handles;
>> +    final int maxtries = Integer.MAX_VALUE;
>>    static final Logger logger = TxnManagerImpl.participantLogger;
>> 
>>    /**
>> @@ -266,13 +267,13 @@
>> 	int tmp = 0;
>> 	int count = 0;
>> 
>> -	checkresults:
>> -	for (int i = 0; i < results.length; i++) {
>> -	    tmp = ((Integer)results[i]).intValue();
>> -
>> -	    if (tmp == COMMITTED)
>> -		count++;
>> +        synchronized (this){
>> +            Iterator i = results.values().iterator();
>> +            while (i.hasNext()){
>> +                tmp = ((Integer)i.next()).intValue();
>> +                if (tmp == COMMITTED) count++;
>> 	}
>> +        }
>> 
>>        if (logger.isLoggable(Level.FINEST)) {
>>            logger.log(Level.FINEST,
>> Index: src/com/sun/jini/mahalo/CommitRecord.java
>> --- src/com/sun/jini/mahalo/CommitRecord.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/CommitRecord.java Locally Modified (Based On LOCAL)
>> @@ -39,7 +39,7 @@
>>    /**
>>     * @serial
>>     */
>> -    ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
>> +    final ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
>> 			       //      We want a list of things.  By using
>> 			       //      an array, we can use the type system
>> 			       //      to guarantee that each thing is a
>> Index: src/com/sun/jini/mahalo/Job.java
>> --- src/com/sun/jini/mahalo/Job.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/Job.java Locally Modified (Based On LOCAL)
>> @@ -19,9 +19,13 @@
>> 
>> import com.sun.jini.thread.TaskManager;
>> import com.sun.jini.thread.WakeupManager;
>> +import java.util.ArrayList;
>> import java.util.HashMap;
>> +import java.util.List;
>> import java.util.Map;
>> import java.util.Set;
>> +import java.util.concurrent.ConcurrentHashMap;
>> +import java.util.concurrent.atomic.AtomicIntegerArray;
>> import java.util.logging.Level;
>> import java.util.logging.Logger;
>> 
>> @@ -34,14 +38,15 @@
>> *
>> */
>> public abstract class Job {
>> -    private TaskManager pool;
>> -    private WakeupManager wm;
>> -    private int pending = -1;
>> -    Object[] results;
>> -    int[] attempts;
>> -    private Map tasks = new HashMap();  //used to maintain account
>> +    private final TaskManager pool;
>> +    private final WakeupManager wm;
>> +    private int pending = -1; // Synchronized on this.
>> +    final Map<Integer,Object> results = new HashMap<Integer,Object>(); // sync on this.
>> +    volatile AtomicIntegerArray attempts; // reference changed while synchronized on this
>> +    private final Map<Object,Integer> tasks = new HashMap<Object,Integer>();  //used to maintain account
>> 					//of the tasks for which
>> 					//the job is responsible
>> +                                        // sync on tasks.
>> 
>>    static final Logger logger = TxnManagerImpl.participantLogger;
>> 
>> @@ -75,23 +80,31 @@
>> 	}
>> 
>> 	if (tmp == null)
>> -	    throw new UnknownTaskException();
>> +	    throw new UnknownTaskException("Task didn't belong to this job");
>> 
>> 	int rank = tmp.intValue();
>> 
>> -	synchronized (attempts) {
>> -	    attempts[rank]++;
>> -	}
>> +//	synchronized (attempts) {
>> +//	    attempts[rank]++;
>> +//	}
>> 
>> -	Object result = doWork(who, param);
>> -	if (result == null)
>> +        attempts.incrementAndGet(rank);
>> +
>> +	Object r = doWork(who, param);
>> +	if (r == null)
>> 	    return false;
>> 
>> 	try {
>> -	    reportDone(who, result);
>> +	    reportDone(who, r);
>> 	} catch (UnknownTaskException e) {
>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>> +            e.printStackTrace(System.err);
>> 	} catch (PartialResultException e) {
>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>> +            e.printStackTrace(System.err);
>> 	} catch (JobException e) {
>> +            logger.log(Level.FINER, "trouble reporting job completion", e);
>> +            e.printStackTrace(System.err);
>> 	}
>> 
>> 	return true;
>> @@ -112,15 +125,14 @@
>> 	    tmp = (Integer)tasks.get(who);
>> 	}
>> 
>> -	if (tmp == null)
>> -	    throw new UnknownTaskException();
>> +	if (tmp == null) throw new UnknownTaskException();
>> 
>> 	int rank = tmp.intValue();
>> -
>> -	synchronized(attempts)  {
>> -	    return attempts[rank];
>> +//	synchronized(attempts)  {
>> +//	    return attempts[rank];
>> +//	}
>> +        return attempts.get(rank);
>> 	}
>> -    }
>> 
>> 
>> 
>> @@ -150,37 +162,39 @@
>>     */
>>    public void scheduleTasks() {
>> 	TaskManager.Task[] tmp = createTasks();
>> -
>> +        int length = tmp.length;
>> 	if (tmp != null) {
>>            if (logger.isLoggable(Level.FINEST)) {
>>                logger.log(Level.FINEST,
>>                    "Job:scheduleTasks with {0} tasks",
>> -                    Integer.valueOf(tmp.length));
>> +                    Integer.valueOf(length));
>>            }
>> 
>> -	    results = new Object[tmp.length];
>> -	    attempts = new int[tmp.length];
>> -	    setPending(tmp.length);
>> +            synchronized (this){ 
>> +                results.clear();
>> +                attempts = new AtomicIntegerArray(length);
>> +                setPending(length);
>> +            }
>> +            for (int i = 0; i < length; i++) {
>> 
>> -	    for (int i = 0; i < tmp.length; i++) {
>> -
>> 		//Record the position if each
>> 		//task for later use when assembling
>> 		//the partial results
>> 
>> 		synchronized(tasks) {
>> 		    tasks.put(tmp[i],Integer.valueOf(i));
>> +                }
>> 		    pool.add(tmp[i]);
>>                    if (logger.isLoggable(Level.FINEST)) {
>>                        logger.log(Level.FINEST,
>>                            "Job:scheduleTasks added {0} to thread pool",
>>                            tmp[i]);
>>                    }
>> -		    attempts[i] = 0;
>> +                attempts.set(i,0);
>> 		}
>> +            
>> 	    }
>> 	}
>> -    }
>> 
>> 
>>    private synchronized void awaitPending(long waitFor) {
>> @@ -289,19 +303,21 @@
>> 	if (position == null) 
>> 	    throw new UnknownTaskException();
>> 
>> -	synchronized(results) {
>> -	    if (results[position.intValue()] == null) {
>> +        synchronized (this){
>> +            Object exists = results.get(position);
>> +            if (exists == null){
>>                if (logger.isLoggable(Level.FINEST)) {
>>                    logger.log(Level.FINEST,
>>                        "Job:reportDone who = {0}, param = {1}",
>> 		        new Object[] { who, param});
>>                }
>> -	        results[position.intValue()] = param;
>> +                results.put(position, param);
>> 	        decrementPending();
>> 	    } else {
>> 	        throw new PartialResultException("result already set");
>> 	    }
>> 	}
>> +        
>>    }
>> 
>> 
>> @@ -347,21 +363,25 @@
>>     * the <code>Job</code>
>>     */
>>    public void stop() {
>> +        Object[] vals;
>> +        synchronized (tasks){
>> 	Set s = tasks.keySet();
>> -	Object[] vals = s.toArray();
>> +            vals = s.toArray();
>> +            tasks.clear();
>> +        }
>> 
>> 	//Remove and interrupt all tasks
>> -
>> -	for (int i = 0; i < vals.length; i++) {
>> +        int l = vals.length;
>> +	for (int i = 0; i < l; i++) {
>> 	    TaskManager.Task t = (TaskManager.Task) vals[i];
>> 	    pool.remove(t);
>> 	}
>> 
>> 	//Erase record of tasks, results and the
>> 	//counting mechanism
>> -
>> -	tasks = new HashMap();
>> +        synchronized (this){
>> 	setPending(-1);
>> -	results = null;
>> +            results.clear();
>>    }
>> }
>> +}
>> Index: src/com/sun/jini/mahalo/JoinStateManager.java
>> --- src/com/sun/jini/mahalo/JoinStateManager.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/JoinStateManager.java Locally Modified (Based On LOCAL)
>> @@ -74,41 +74,41 @@
>>    private static final Logger persistenceLogger = TxnManagerImpl.persistenceLogger;
>> 
>>    /** <code>ProxyPreparer</code> for <code>LookupLocators</code> */
>> -    private ProxyPreparer lookupLocatorPreparer;
>> +    private volatile ProxyPreparer lookupLocatorPreparer;
>> 
>>    /**
>>     * Object used to find lookups. Has to implement DiscoveryManagement
>>     * and DiscoveryLocatorManagement as well as DiscoveryGroupManagement.
>>     */
>> -    private DiscoveryManagement dm;
>> +    private volatile DiscoveryManagement dm;
>> 
>>    /**
>>     * <code>JoinManager</code> that is handling the details of binding
>>     * into Jini lookup services.
>>     */
>> -    private JoinManager  mgr;
>> +    private volatile JoinManager  mgr;
>> 
>>    /**
>>     * The object coordinating our persistent state.
>>     */
>> -    private ReliableLog log;
>> +    private volatile ReliableLog log;
>> 
>>    /**
>>     * The join state, this data needs to be persisted between restarts
>>     */
>> -    private Entry[]		attributes;
>> -    private LookupLocator[]	locators;
>> -    private String[]		groups;
>> +    private volatile Entry[]		attributes;
>> +    private volatile LookupLocator[]	locators;
>> +    private volatile String[]		groups;
>> 
>>    /** Service's internal <code>Uuid</code> which needs to be persisted */
>> -    private Uuid		serviceUuid;
>> +    private volatile Uuid		serviceUuid;
>> 
>>    /**
>>     * Conceptually, true if this is the first time this
>>     * service has come up, implemented as if there was
>>     * no previous state then this is the first time.
>>     */
>> -    private boolean initial = true;
>> +    private volatile boolean initial = true;
>> 
>>    /**
>>     * Simple constructor.
>> Index: src/com/sun/jini/mahalo/LeaseExpirationMgr.java
>> --- src/com/sun/jini/mahalo/LeaseExpirationMgr.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/LeaseExpirationMgr.java Locally Modified (Based On LOCAL)
>> @@ -57,9 +57,9 @@
>> 
>> 
>>    // Map of resources to tickets
>> -    private WeakTable		ticketMap = new WeakTable(this); 
>> -    private Expirer		landlord;
>> -    private WakeupManager expirationQueue
>> +    private final WeakTable		ticketMap = new WeakTable(this); 
>> +    private final Expirer		landlord;
>> +    private final WakeupManager expirationQueue
>>        = new WakeupManager(new WakeupManager.ThreadDesc(null, true));
>> 
>>    /**
>> Index: src/com/sun/jini/mahalo/ParticipantHandle.java
>> --- src/com/sun/jini/mahalo/ParticipantHandle.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/ParticipantHandle.java Locally Modified (Based On LOCAL)
>> @@ -38,17 +38,17 @@
>>    /**
>>     * Cached reference to prepared participant.
>>     */
>> -    private transient TransactionParticipant preparedPart;
>> +    private volatile transient TransactionParticipant preparedPart;
>> 
>>    /**
>>     * @serial
>>     */
>> -    private StorableObject storedpart;
>> +    private final StorableObject storedpart;
>> 
>>    /**
>>     * @serial
>>     */
>> -    private long crashcount = 0;
>> +    private volatile long crashcount = 0;
>> 
>>    /**
>>     * @serial
>> @@ -70,6 +70,7 @@
>>        if (preparedPart == null) 
>> 	    throw new NullPointerException(
>> 	        "TransactionParticipant argument cannot be null");
>> +        StorableObject storedpart = null;
>> 	try {
>> 	    storedpart = new StorableObject(preparedPart);
>> 	    this.preparedPart = preparedPart;
>> @@ -80,6 +81,7 @@
>> 		    "Cannot store the TransactionParticipant", re);
>> 	    }
>> 	}
>> +        this.storedpart = storedpart;
>> 	this.prepstate = ACTIVE;
>>    }
>> 
>> Index: src/com/sun/jini/mahalo/ParticipantModRecord.java
>> --- src/com/sun/jini/mahalo/ParticipantModRecord.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/ParticipantModRecord.java Locally Modified (Based On LOCAL)
>> @@ -38,12 +38,12 @@
>>    /**
>>     * @serial
>>     */
>> -    private ParticipantHandle part;
>> +    private final ParticipantHandle part;
>> 
>>    /**
>>     * @serial
>>     */
>> -    private int result;
>> +    private final int result;
>> 
>>    ParticipantModRecord(ParticipantHandle part, int result) {
>> 	if (part == null)
>> Index: src/com/sun/jini/mahalo/ParticipantTask.java
>> --- src/com/sun/jini/mahalo/ParticipantTask.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/ParticipantTask.java Locally Modified (Based On LOCAL)
>> @@ -17,6 +17,7 @@
>> */
>> package com.sun.jini.mahalo;
>> 
>> +import com.sun.jini.logging.Levels;
>> import com.sun.jini.thread.RetryTask;
>> import com.sun.jini.thread.TaskManager;
>> import com.sun.jini.thread.WakeupManager;
>> @@ -35,8 +36,8 @@
>> * @see TaskManager
>> */
>> public class ParticipantTask extends RetryTask {
>> -    ParticipantHandle handle;
>> -    Job myjob;
>> +    final ParticipantHandle handle;
>> +    final Job myjob;
>>    private static final Logger operationsLogger = 
>>        TxnManagerImpl.operationsLogger;
>> 	
>> @@ -81,9 +82,11 @@
>> 	} catch (UnknownTaskException ute) {
>> 	    //If task doesn't belong to the
>> 	    //Job, then stop doing work.
>> +            logger.log(Level.FINE, "Task didn't belong to job",ute);
>> +            ute.printStackTrace(System.err);
>> 	    result = true;
>> 	} catch (JobException je) {
>> -	    je.printStackTrace();
>> +	    je.printStackTrace(System.err);
>> 	}
>>        if (operationsLogger.isLoggable(Level.FINER)) {
>>            operationsLogger.exiting(ParticipantTask.class.getName(), 
>> Index: src/com/sun/jini/mahalo/PrepareAndCommitJob.java
>> --- src/com/sun/jini/mahalo/PrepareAndCommitJob.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/PrepareAndCommitJob.java Locally Modified (Based On LOCAL)
>> @@ -45,10 +45,10 @@
>> * @see net.jini.core.transaction.server.TransactionParticipant
>> */
>> public class PrepareAndCommitJob extends Job implements TransactionConstants {
>> -    ServerTransaction tr;
>> -    ClientLog log;
>> -    ParticipantHandle handle;
>> -    int maxtries = 5;
>> +    final ServerTransaction tr;
>> +    final ClientLog log;
>> +    final ParticipantHandle handle;
>> +    final int maxtries = 5;
>> 
>>    /*
>>     * Field that holds the last received remote exception, if any.
>> @@ -290,7 +290,9 @@
>> 
>> 	int prepstate = NOTCHANGED;
>> 
>> -	prepstate = ((Integer)results[0]).intValue();
>> +        synchronized (this){
>> +            prepstate = ((Integer) results.get(Integer.valueOf(0))).intValue();
>> +        }
>> 
>>        Integer result = Integer.valueOf(prepstate);
>>        if (operationsLogger.isLoggable(Level.FINER)) {
>> Index: src/com/sun/jini/mahalo/PrepareJob.java
>> --- src/com/sun/jini/mahalo/PrepareJob.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/PrepareJob.java Locally Modified (Based On LOCAL)
>> @@ -22,6 +22,7 @@
>> import com.sun.jini.thread.TaskManager;
>> import com.sun.jini.thread.WakeupManager;
>> import java.rmi.RemoteException;
>> +import java.util.Iterator;
>> import java.util.logging.Level;
>> import java.util.logging.Logger;
>> import net.jini.core.transaction.Transaction;
>> @@ -273,10 +274,11 @@
>> 	int prepstate = NOTCHANGED;
>> 	int tmp = 0;
>> 
>> -	checkresults:
>> -	for (int i = 0; i < results.length; i++) {
>> -	    tmp = ((Integer)results[i]).intValue();
>> -
>> +        synchronized (this){
>> +            Iterator i = results.values().iterator();
>> +            checkresult:
>> +            while (i.hasNext()){
>> +                tmp = ((Integer) i.next()).intValue();
>> 	    switch(tmp) {
>> 	      case NOTCHANGED:
>> 		//Does not affect the prepstate
>> @@ -288,7 +290,7 @@
>> 		//aborts the whole transaction.
>> 
>> 		prepstate = ABORTED;
>> -		break checkresults;
>> +                    break checkresult;
>> 
>> 	      case PREPARED:
>> 		//changes the state to PREPARED only
>> @@ -298,11 +300,13 @@
>> 		break;
>> 	    }
>> 	}
>> -	Integer result = Integer.valueOf(prepstate);
>> +        }
>> +        
>> +	Integer r = Integer.valueOf(prepstate);
>>        if (operationsLogger.isLoggable(Level.FINER)) {
>>            operationsLogger.exiting(PrepareJob.class.getName(),
>> -                "computeResult", result);
>> +                "computeResult", r);
>> 	}
>> -	return result;
>> +	return r;
>>    }
>> }
>> Index: src/com/sun/jini/mahalo/SettlerTask.java
>> --- src/com/sun/jini/mahalo/SettlerTask.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/SettlerTask.java Locally Modified (Based On LOCAL)
>> @@ -39,10 +39,10 @@
>> */
>> 
>> public class SettlerTask extends RetryTask implements TransactionConstants {
>> -    private long tid;
>> -    private int attempt;
>> -    private int maxtries = Integer.MAX_VALUE;
>> -    private TransactionManager txnmgr;
>> +    private final long tid;
>> +    private int attempt; // sync on this.
>> +    private final int maxtries = Integer.MAX_VALUE;
>> +    private final TransactionManager txnmgr;
>> 
>>    /** Logger for operations related messages */
>>    private static final Logger operationsLogger = 
>> @@ -89,10 +89,12 @@
>> 	        "tryOnce");
>> 	}
>>        try {
>> +            synchronized (this){
>> 	    if (attempt >= maxtries)
>> 		return true;
>> 
>> 	    attempt++;
>> +            }
>> 
>> 	    if (transactionsLogger.isLoggable(Level.FINEST)) {
>>                transactionsLogger.log(Level.FINEST,
>> Index: src/com/sun/jini/mahalo/StorableObject.java
>> --- src/com/sun/jini/mahalo/StorableObject.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/StorableObject.java Locally Modified (Based On LOCAL)
>> @@ -19,6 +19,7 @@
>> package com.sun.jini.mahalo;
>> 
>> import java.io.IOException;
>> +import java.io.ObjectInputStream;
>> import java.rmi.MarshalledObject;
>> import java.rmi.RemoteException;
>> 
>> @@ -39,8 +40,8 @@
>>    /**
>>     * @serial
>>     */
>> -    private MarshalledObject	bytes;	// the serialized bytes
>> -    private transient Object	obj;	// the cached object reference
>> +    private final MarshalledObject	bytes;	// the serialized bytes
>> +    private volatile transient Object	obj;	// the cached object reference
>> 
>>    private static final boolean DEBUG = false;
>>    private static final long serialVersionUID = -3793675220968988873L;
>> @@ -50,16 +51,25 @@
>>     * in a <code>MarshalledObject</code>.
>>     */
>>    public StorableObject(Object obj) throws RemoteException {
>> +	this(obj, toMO(obj));
>> +    }
>> +    
>> +    private static MarshalledObject toMO(Object obj) throws RemoteException{
>> 	try {
>> -	    bytes = new MarshalledObject(obj);
>> -	    this.obj = obj;
>> -	} catch (RemoteException e) {
>> +            return new MarshalledObject(obj);
>> +        } catch (RemoteException e){
>> 	    throw e;
>> -	} catch (IOException e) {
>> +        } catch (IOException e){
>> 	    fatalError("can't encode object", e);
>> 	}
>> +        return null; //Unreachable.
>>    }
>> 
>> +    private StorableObject (Object obj, MarshalledObject mo){
>> +        bytes = mo;
>> +        this.obj = obj;
>> +    }
>> +    
>>    /**
>>     * Return the <code>hashCode</code> of the <code>MarshalledObject</code>.
>>     */
>> @@ -103,6 +113,12 @@
>> 	return null;	// not reached, but compiler doesn't know
>>    }
>> 
>> +    private void readObject(ObjectInputStream s)
>> +                                   throws IOException, ClassNotFoundException
>> +        {
>> +            s.defaultReadObject(); // Just in case we change serial form later.
>> +        }
>> +
>>    /**
>>     * Unrecoverable error happened -- show it and give up the ghost.
>>     */
>> Index: src/com/sun/jini/mahalo/TxnManagerImpl.java
>> --- src/com/sun/jini/mahalo/TxnManagerImpl.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/TxnManagerImpl.java Locally Modified (Based On LOCAL)
>> @@ -62,6 +62,7 @@
>> import java.util.Iterator;
>> import java.util.Map;
>> import java.util.Vector;
>> +import java.util.concurrent.ConcurrentMap;
>> import java.util.logging.Level;
>> import java.util.logging.Logger;
>> 
>> @@ -149,28 +150,6 @@
>>    static final Logger persistenceLogger = 
>>        Logger.getLogger(TxnManager.MAHALO + ".persistence");
>> 
>> -    /* At some point earlier in the development, it appears this object
>> -     * was Serializable, or was declared so, such that it replaced itself
>> -     * with a proxy stub.  This is a test to ensure serialization doesn't
>> -     * occur.
>> -     */
>> -    
>> -    private void writeObject(java.io.ObjectOutputStream out)
>> -     throws IOException {
>> -        throw new IOException("Serialization not supported");
>> -    }
>> -    private void readObject(java.io.ObjectInputStream in)
>> -     throws IOException, ClassNotFoundException {
>> -        throw new IOException("Serialization not supported");
>> -    }
>> -    private void readObjectNoData() 
>> -     throws ObjectStreamException{
>> -        throw new ObjectStreamException("Serialization not supported"){
>> -            private static final long serialVersionUID = 1L;
>> -        };
>> -    }
>> - 
>> -    
>>    private volatile LogManager logmgr;
>>    /* Retrieve values from properties.          */
>>    /* Its important here to schedule SettlerTasks on a */
>> @@ -186,7 +165,7 @@
>>    private final WakeupManager taskWakeupMgr;
>>    /* Map of transaction ids are their associated, internal 
>>     * transaction representations */
>> -    private final Map<Long,TxnManagerTransaction> txns;
>> +    private final ConcurrentMap<Long,TxnManagerTransaction> txns;
>>    private final Vector<Long> unsettledtxns = new Vector<Long>();
>>    private final InterruptedStatusThread settleThread;
>>    private final String persistenceDirectory;
>> @@ -390,7 +369,7 @@
>>                settleThread = init.settleThread;
>>            } else {
>>                // Assign init fields
>> -                txns = Collections.emptyMap();
>> +                txns = null;
>>                /* Retrieve values from properties.          */
>>                activationSystem = null;
>>                activationID = activID;
>> @@ -627,8 +606,7 @@
>> 	        "prepared participant: {0}", preparedTarget);
>> 	}
>> 
>> -        TxnManagerTransaction txntr =
>> -		(TxnManagerTransaction) txns.get(Long.valueOf(id));
>> +        TxnManagerTransaction txntr = txns.get(Long.valueOf(id));
>> 
>> 	if (txntr == null)
>> 	    throw new UnknownTransactionException("unknown transaction");
>> @@ -645,6 +623,7 @@
>>    public int getState(long id)
>>        throws UnknownTransactionException
>>    {
>> +        
>>        if (operationsLogger.isLoggable(Level.FINER)) {
>>            operationsLogger.entering(
>> 		TxnManagerImpl.class.getName(), "getState", 
>> @@ -652,9 +631,8 @@
>> 	}
>>        readyState.check();
>> 
>> -        TxnManagerTransaction txntr =
>> -	        (TxnManagerTransaction) txns.get(Long.valueOf(id));
>> -
>> +        TxnManagerTransaction txntr = null;
>> +                txntr = txns.get(Long.valueOf(id));
>> 	if (txntr == null)
>> 	    throw new UnknownTransactionException("unknown transaction");
>>        /* Expiration checks are only meaningful for active transactions. */
>> @@ -669,17 +647,18 @@
>> 	 * a false result.
>> 	 */
>> //TODO - need better locking here. getState and expiration need to be checked atomically	
>> -        int state = txntr.getState();
>> -        if (state == ACTIVE && !ensureCurrent(txntr)) 
>> -	    throw new UnknownTransactionException("unknown transaction");
>> -	    
>> +        try{
>> +            int state = txntr.atomicCheckExpirationIfActive();
>> 	if (operationsLogger.isLoggable(Level.FINER)) {
>>            operationsLogger.exiting(
>> 		TxnManagerImpl.class.getName(), "getState", 
>> 	        Integer.valueOf(state));
>> 	}
>> 	return state;
>> +        } catch (TransactionException ex) {
>> +            throw new UnknownTransactionException("unknown transaction");
>>    }
>> +    }
>> 
>> 
>>    public void commit(long id)
>> @@ -901,12 +880,14 @@
>>                    transactionsLogger.log(Level.FINEST,
>>                        "Settler waiting");
>> 	        }
>> -		wait();
>> -
>> -	        if (transactionsLogger.isLoggable(Level.FINEST)) {
>> -                    transactionsLogger.log(Level.FINEST,
>> -                        "Settler notified");
>> -	        }
>> +                // Don't wait forever, in case we're not notified, break out
>> +                // early and check condition.
>> +		wait(10000L); 
>> +                // Due to spurious wakeup and break out after ten seconds, the following log message is inaccurate.
>> +//	        if (transactionsLogger.isLoggable(Level.FINEST)) {
>> +//                    transactionsLogger.log(Level.FINEST,
>> +//                        "Settler notified");
>> +//	        }
>> 		continue;
>> 	    }
>> 
>> @@ -1018,6 +999,7 @@
>> 
>> 	// synchronize on the resource so there is not a race condition
>> 	// between renew and expiration
>> +        /* TODO check if synchronization correct */
>> 	Result r;
>> 	synchronized (txntr) {
>> //TODO - check for ACTIVE too?
>> @@ -1066,7 +1048,7 @@
>> 
>>        try {
>>            // getState and expiration checked atomically
>> -            txntr.checkStateActive(); // Throws UnknownLeaseException if state not ACTIVE.
>> +            txntr.atomicCheckStateActive(); // throws TransactionException if state not ACTIVE.
>>            // State is still active, make it expire.
>>            txntr.setExpiration(0);	// Mark as done
>>            abort(((Long)tid).longValue(), false);
>> Index: src/com/sun/jini/mahalo/TxnManagerImplInitializer.java
>> --- src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Locally Modified (Based On LOCAL)
>> @@ -38,6 +38,8 @@
>> import java.util.HashMap;
>> import java.util.Iterator;
>> import java.util.Map;
>> +import java.util.concurrent.ConcurrentHashMap;
>> +import java.util.concurrent.ConcurrentMap;
>> import java.util.logging.Level;
>> import net.jini.activation.ActivationExporter;
>> import net.jini.config.Configuration;
>> @@ -64,7 +66,7 @@
>>    int taskthreads = 50;
>>    long tasktimeout = 1000 * 15;
>>    float taskload = 1.0F;
>> -    Map<Long, TxnManagerTransaction> txns = Collections.synchronizedMap(new HashMap<Long, TxnManagerTransaction>());
>> +    ConcurrentMap<Long, TxnManagerTransaction> txns = new ConcurrentHashMap<Long, TxnManagerTransaction>();
>>    /* Retrieve values from properties.          */
>>    ActivationSystem activationSystem = null;
>>    boolean activationPrepared = false;
>> Index: src/com/sun/jini/mahalo/TxnManagerTransaction.java
>> --- src/com/sun/jini/mahalo/TxnManagerTransaction.java Base (BASE)
>> +++ src/com/sun/jini/mahalo/TxnManagerTransaction.java Locally Modified (Based On LOCAL)
>> @@ -135,17 +135,17 @@
>>    /**
>>     * @serial
>>     */
>> -    private int trstate;
>> +    private int trstate; //sync on stateLock
>> 
>>    /**
>>     * @serial
>>     */
>> -    private long expires;		//expiration time
>> +    private long expires;		//expiration time sync on leaseLock
>> 
>>    /**
>>     * @serial
>>     */
>> -    private LogManager logmgr;
>> +    private final LogManager logmgr;
>> 
>> 
>>   /**
>> @@ -180,27 +180,27 @@
>>    *
>>    * @serial
>>    */
>> -    private TaskManager threadpool;
>> +    private final TaskManager threadpool;
>> 
>>    /**
>>     * @serial
>>     */
>> -    private WakeupManager wm;
>> +    private final WakeupManager wm;
>> 
>>    /**
>>     * @serial
>>     */
>> -    private TxnSettler settler;
>> +    private final TxnSettler settler;
>> 
>>    /**
>>     * @serial
>>     */
>> -    private Job job;
>> +    private Job job; // sync with jobLock
>> 
>>    /**
>>     * @serial
>>     */
>> -    private Uuid uuid;
>> +    private final Uuid uuid;
>> 
>>   /**
>>    * Interlock for the expiration time since
>> @@ -524,12 +524,21 @@
>> 	}
>>    }
>> 
>> +    public int atomicCheckExpirationIfActive() throws TransactionException {
>> +        synchronized (stateLock){
>> +            int state = getState();
>> +            if (state == ACTIVE && !(getExpiration() > System.currentTimeMillis())) 
>> +                throw new TransactionException("unknown transaction");
>> +            return state;
>> +        }
>> +    }
>> +
>>    /**
>>     * Atomic check that state is ACTIVE.
>>     * @return ACTIVE if lease hasn't expired.
>>     * @throws TransactionException otherwise.
>>     */
>> -    public int checkStateActive() throws TransactionException {
>> +    public int atomicCheckStateActive() throws TransactionException {
>>        synchronized (stateLock){
>>            int state = getState();
>>            if ((state == ACTIVE && getExpiration()==0) || (state != ACTIVE)) {
>> @@ -839,13 +848,15 @@
>> 								"ABORTED");
>> 		  }
>> 
>> -                  if (getState() != COMMITTED)
>> +                  if (getState() != COMMITTED){
>> +                      synchronized (jobLock){
>>                        throw new
>>                            InternalManagerException("TxnManagerTransaction: " +
>>                                    "commit: " + job + " got bad state: " +
>>                                    TxnConstants.getName(result.intValue()));
>> +                      }
>> +                  }
>> 
>> -
>> 		now = System.currentTimeMillis();
>> 		transpired = now - starttime;
>> 
>> Index: src/com/sun/jini/mercury/MailboxImpl.java
>> --- src/com/sun/jini/mercury/MailboxImpl.java Base (BASE)
>> +++ src/com/sun/jini/mercury/MailboxImpl.java Locally Modified (Based On LOCAL)
>> @@ -419,7 +419,7 @@
>>    // constructor thread and set to null after starting.
>>    private Configuration config;
>>    private Throwable thrown;
>> -    private volatile boolean started = false;
>> +    private boolean started = false;
>> 
>>    ///////////////////////
>>    // Activation Methods
>> @@ -1071,8 +1071,8 @@
>> //    } // End doInit()
>> //    
>>    public void start() throws Exception {
>> -        if (started) return;
>>        concurrentObj.writeLock();
>> +        if (started) return;
>>        started = true; // mutual exclusion
>>        try {
>>            if (thrown != null) throw thrown;
>> Index: src/com/sun/jini/outrigger/EventRegistrationWatcher.java
>> --- src/com/sun/jini/outrigger/EventRegistrationWatcher.java Base (BASE)
>> +++ src/com/sun/jini/outrigger/EventRegistrationWatcher.java Locally Modified (Based On LOCAL)
>> @@ -240,7 +240,7 @@
>>     * @return The unique identifier associated with this
>>     * watcher.
>>     */
>> -    public Uuid getCookie() {
>> +    public synchronized Uuid getCookie() {
>> 	return cookie;
>>    }
>> 
>> Index: src/com/sun/jini/outrigger/OutriggerServerImpl.java
>> --- src/com/sun/jini/outrigger/OutriggerServerImpl.java Base (BASE)
>> +++ src/com/sun/jini/outrigger/OutriggerServerImpl.java Locally Modified (Based On LOCAL)
>> @@ -647,6 +647,7 @@
>>        if (except != null) throw except;
>>        try {
>>            // This takes a while the first time, so let's get it going
>> +            txnMonitor.start();
>>            starter.start();
>> 
>>            // Get store from configuration
>> Index: src/com/sun/jini/outrigger/StorableEventWatcher.java
>> --- src/com/sun/jini/outrigger/StorableEventWatcher.java Base (BASE)
>> +++ src/com/sun/jini/outrigger/StorableEventWatcher.java Locally Modified (Based On LOCAL)
>> @@ -36,7 +36,7 @@
>>    implements StorableResource
>> {
>>    /** The listener that should be notified of matches */
>> -    private StorableReference listener;
>> +    private volatile StorableReference listener;
>> 
>>    /**
>>     * Used during log recovery to create a mostly empty
>> @@ -115,7 +115,7 @@
>>     * @param expired <code>true</code> if being called from 
>>     *        <code>removeIfExpired</code> and false otherwise. 
>>     */
>> -    void cleanup(TemplateHandle owner, boolean expired) {
>> +    synchronized void cleanup(TemplateHandle owner, boolean expired) {
>> 	if (expired)
>> 	    owner.getServer().scheduleCancelOp(cookie);
>> 	else 
>> @@ -126,7 +126,7 @@
>>    /**  
>>     * Store the persistent fields 
>>     */
>> -    public void store(ObjectOutputStream out) throws IOException {
>> +    public synchronized void store(ObjectOutputStream out) throws IOException {
>> 	cookie.write(out);
>> 	out.writeLong(expiration);
>> 	out.writeLong(eventID);
>> @@ -137,7 +137,7 @@
>>    /**
>>     * Restore the persistent fields
>>     */
>> -    public void restore(ObjectInputStream in) 
>> +    public synchronized void restore(ObjectInputStream in) 
>> 	throws IOException, ClassNotFoundException 
>>    {
>> 	cookie = UuidFactory.read(in);
>> Index: src/com/sun/jini/outrigger/TxnMonitor.java
>> --- src/com/sun/jini/outrigger/TxnMonitor.java Base (BASE)
>> +++ src/com/sun/jini/outrigger/TxnMonitor.java Locally Modified (Based On LOCAL)
>> @@ -51,8 +51,8 @@
>>     * @see #pending
>>     */
>>    private static class ToMonitor {
>> -	QueryWatcher	query;         // query governing interest in txns
>> -	Collection	txns;	       // the transactions to monitor
>> +	final QueryWatcher	query;         // query governing interest in txns
>> +	final Collection	txns;	       // the transactions to monitor
>> 
>> 	ToMonitor(QueryWatcher query, Collection txns) {
>> 	    this.query = query;
>> @@ -71,7 +71,7 @@
>>     * @see OutriggerServerImpl#getMatch 
>>     */
>>    // @see #ToMonitor
>> -    private LinkedList pending = new LinkedList();
>> +    private final LinkedList pending = new LinkedList();
>> 
>>    /** wakeup manager for <code>TxnMonitorTask</code>s */
>>    private final WakeupManager wakeupMgr = 
>> @@ -80,21 +80,23 @@
>>    /**
>>     * The manager for <code>TxnMonitorTask</code> objects.
>>     */
>> -    private TaskManager taskManager;
>> +    private final TaskManager taskManager;
>> 
>>    /**
>>     * The space we belong to.  Needed for aborts.
>>     */
>> -    private OutriggerServerImpl	space;
>> +    private final OutriggerServerImpl	space;
>> 
>>    /**
>>     * The thread running us.
>>     */
>> -    private Thread ourThread;
>> +    private final Thread ourThread;
>> 
>>    /** Set when we are told to stop */
>> -    private boolean die = false;
>> +    private volatile boolean die = false;
>> 
>> +    private volatile boolean started = false;
>> +
>>    /** Logger for logging transaction related information */
>>    private static final Logger logger = 
>> 	Logger.getLogger(OutriggerServerImpl.txnLoggerName);
>> @@ -115,8 +117,15 @@
>> 
>>        ourThread = new Thread(this, "TxnMonitor");
>> 	ourThread.setDaemon(true);
>> +//        ourThread.start();
>> +    }
>> +    
>> +    public void start(){
>> +        synchronized (this){
>>        ourThread.start();
>> +            started = true;
>>    }
>> +    }
>> 
>>    public void destroy() {
>>        taskManager.terminate();
>> @@ -128,7 +137,7 @@
>> 	}
>> 
>>        try {
>> -	    ourThread.join();
>> +	    if (started) ourThread.join();
>> 	} catch(InterruptedException ie) {
>> 	    // ignore
>> 	}
>> Index: src/com/sun/jini/outrigger/TypeTree.java
>> --- src/com/sun/jini/outrigger/TypeTree.java Base (BASE)
>> +++ src/com/sun/jini/outrigger/TypeTree.java Locally Modified (Based On LOCAL)
>> @@ -39,7 +39,7 @@
>> */
>> class TypeTree {
>>    /** For each type, a vector of known subtypes */
>> -    private Hashtable subclasses = new Hashtable();
>> +    private final Hashtable<String,Vector> subclasses = new Hashtable<String,Vector>();
>> 
>>    /**
>>     * A generator used to randomize the order of iterator returns
>> @@ -57,8 +57,10 @@
>>     * Return the vector of subclasses for the given class.
>>     */
>>    private Vector classVector(String whichClass) {
>> +        synchronized (subclasses){
>> 	return (Vector) subclasses.get(whichClass);
>>    }
>> +    }
>> 
>>    /**
>>     * An iterator that will walk through a list of known types.
>> Index: src/com/sun/jini/thread/RetryTask.java
>> --- src/com/sun/jini/thread/RetryTask.java Base (BASE)
>> +++ src/com/sun/jini/thread/RetryTask.java Locally Modified (Based On LOCAL)
>> @@ -64,7 +64,7 @@
>> import com.sun.jini.thread.WakeupManager.Ticket;
>> 
>> public abstract class RetryTask implements TaskManager.Task, TimeConstants {
>> -    private TaskManager	  manager;	// the TaskManager for this task
>> +    private final TaskManager	  manager;	// the TaskManager for this task
>>    private RetryTime	  retry;	// the retry object for this task
>>    private boolean	  cancelled;	// have we been cancelled?
>>    private boolean	  complete;	// have we completed successfully?
>> @@ -72,7 +72,7 @@
>>    private long	  startTime;	// the time when we were created or 
>>                                        //   last reset
>>    private int		  attempt;	// the current attempt number
>> -    private WakeupManager wakeup;       // WakeupManager for retry scheduling
>> +    private final WakeupManager wakeup;       // WakeupManager for retry scheduling
>> 
>>    /**
>>     * Default delay backoff times.  These are converted from
>> @@ -91,7 +91,7 @@
>>    };
>> 
>>    /** Logger for this class */
>> -    private static final Logger logger = 
>> +    protected static final Logger logger = 
>> 	Logger.getLogger("com.sun.jini.thread.RetryTask");
>> 
>>    /**
>> @@ -128,7 +128,14 @@
>> 		return;			// do nothing
>> 	}
>> 
>> -	boolean success = tryOnce();
>> +	boolean success = false;
>> +        try {
>> +            success = tryOnce();
>> +        } catch (Throwable t){
>> +            t.printStackTrace(System.err);
>> +            if (t instanceof Error) throw (Error) t;
>> +            if (t instanceof RuntimeException) throw (RuntimeException) t;
>> +        }
>> 
>> 	synchronized (this) {
>> 	    if (!success) {		// if at first we don't succeed ...
>> Index: src/com/sun/jini/thread/TaskManager.java
>> --- src/com/sun/jini/thread/TaskManager.java Base (BASE)
>> +++ src/com/sun/jini/thread/TaskManager.java Locally Modified (Based On LOCAL)
>> @@ -22,6 +22,7 @@
>> import java.util.Collections;
>> import java.util.Iterator;
>> import java.util.List;
>> +import java.util.concurrent.CopyOnWriteArrayList;
>> import java.util.logging.Level;
>> import java.util.logging.Logger;
>> 
>> @@ -77,13 +78,13 @@
>> 	Logger.getLogger("com.sun.jini.thread.TaskManager");
>> 
>>    /** Active and pending tasks */
>> -    protected final ArrayList tasks = new ArrayList();
>> +    protected final ArrayList tasks = new ArrayList(); //sync on this
>>    /** Index of the first pending task; all earlier tasks are active */
>> -    protected int firstPending = 0;
>> +    protected int firstPending = 0;//sync on this
>>    /** Read-only view of tasks */
>> -    protected final List roTasks = Collections.unmodifiableList(tasks);
>> +    protected final List roTasks = Collections.unmodifiableList(tasks); // sync on this
>>    /** Active threads */
>> -    protected final List threads = new ArrayList();
>> +    protected final List threads = new ArrayList(); //sync on this
>>    /** Maximum number of threads allowed */
>>    protected final int maxThreads;
>>    /** Idle time before a thread should exit */
>> @@ -91,7 +92,7 @@
>>    /** Threshold for creating new threads */
>>    protected final float loadFactor;
>>    /** True if manager has been terminated */
>> -    protected boolean terminated = false;
>> +    protected boolean terminated = false; //sync on this
>> 
>>    /**
>>     * Create a task manager with maxThreads = 10, timeout = 15 seconds,
>> @@ -256,7 +257,7 @@
>> 
>>    /** Return all pending tasks.  A new list is returned each time. */
>>    public synchronized ArrayList getPending() {
>> -	ArrayList tc = (ArrayList)tasks.clone();
>> +	ArrayList tc = new ArrayList(tasks);
>> 	for (int i = firstPending; --i >= 0; ) {
>> 	    tc.remove(0);
>> 	}
>> @@ -271,7 +272,7 @@
>>    private class TaskThread extends Thread {
>> 
>> 	/** The task being run, if any */
>> -	public Task task = null;
>> +	public Task task = null; // sync access on TaskManager.this
>> 
>> 	public TaskThread() {
>> 	    super("task");
>> @@ -303,6 +304,7 @@
>> 
>> 	public void run() {
>> 	    while (true) {
>> +                Task tsk = null;
>> 		synchronized (TaskManager.this) {
>> 		    if (terminated)
>> 			return;
>> @@ -327,9 +329,10 @@
>> 			    return;
>> 			}
>> 		    }
>> +                    tsk = task;  
>> 		}
>> 		try {
>> -		    task.run();
>> +		    tsk.run();
>> 		} catch (Throwable t) {
>> 		    try {
>> 			logger.log(Level.WARNING, "Task.run exception", t);
>> Index: src/com/sun/jini/thread/WakeupManager.java
>> --- src/com/sun/jini/thread/WakeupManager.java Base (BASE)
>> +++ src/com/sun/jini/thread/WakeupManager.java Locally Modified (Based On LOCAL)
>> @@ -493,7 +493,7 @@
>>     * Assumes the caller holds the lock on contents.
>>     */
>>    private void checkHead() {
>> -	assert Thread.holdsLock(contents);
>> +        synchronized (contents){
>> 	final Ticket oldHead = head;
>> 
>> 	if (contents.isEmpty())
>> @@ -507,6 +507,7 @@
>> 	// needs to wake up and change its sleep time.
>> 	contents.notifyAll();
>>    }
>> +    }
>> 
>>    /**
>>     * Return whether the queue is currently empty.
>> Index: src/net/jini/lookup/JoinManager.java
>> --- src/net/jini/lookup/JoinManager.java Base (BASE)
>> +++ src/net/jini/lookup/JoinManager.java Locally Modified (Based On LOCAL)
>> @@ -563,10 +563,11 @@
>>    private class ProxyRegTask extends RetryTask {
>>        private final long[] sleepTime = { 5*1000, 10*1000, 15*1000,
>>                                          20*1000, 25*1000, 30*1000 };
>> -        protected int tryIndx  = 0;
>> -        protected int nRetries = 0;
>> -        protected ProxyReg proxyReg;
>> -        protected int seqN;
>> +        // volatile fields only mutated while synchronized on proxyReg.taskList
>> +        private volatile int tryIndx  = 0;
>> +        private volatile int nRetries = 0;
>> +        private final ProxyReg proxyReg;
>> +        private volatile int seqN;
>> 
>>        /** Basic constructor; simply stores the input parameters */
>>        ProxyRegTask(ProxyReg proxyReg, int seqN) {
>> @@ -611,10 +612,11 @@
>>                        if( !proxyReg.taskList.isEmpty() ) {
>>                            proxyReg.taskList.remove(0);
>>                        }//endif
>> -                    }//end sync
>>                    /* reset the retry info for the next task in the list */
>>                    tryIndx  = 0;
>>                    nRetries = 0;
>> +                    }//end sync
>> +                    
>>                } catch (Exception e) {
>>                    return stopTrying(e);
>>                }
>> @@ -627,8 +629,10 @@
>>         */
>>        public long retryTime() {
>> 	    long nextTryTime = System.currentTimeMillis() + sleepTime[tryIndx];
>> +            synchronized (proxyReg.taskList){
>> 	    if(tryIndx < sleepTime.length-1)  tryIndx++;//don't go past end
>>            nRetries++;
>> +            }
>>            return nextTryTime;
>>        }//end retryTime
>> 
>> @@ -737,7 +741,7 @@
>>    private abstract class JoinTask {
>> 
>>        /** Data structure referencing the task's associated lookup service */
>> -        protected ProxyReg proxyReg;
>> +        protected final ProxyReg proxyReg;
>> 
>>        /** Basic constructor; simply stores the input parameters */
>>        JoinTask(ProxyReg proxyReg) {
>> @@ -758,7 +762,7 @@
>>         *  must not change during the registration process performed in
>>         *  this this task.
>>         */
>> -        Entry[] regAttrs;
>> +        final Entry[] regAttrs;
>> 
>>        /** Constructor that associates this task with the lookup service
>>         *  referenced in the given <code>ProxyReg</code> parameter.
>> @@ -889,9 +893,10 @@
>>         */
>>        public void run() {
>>            logger.finest("JoinManager --> DiscardProxyTask started");
>> -            if( (proxyReg != null) && (proxyReg.serviceLease != null) ) {
>> +            Lease svcLease = proxyReg != null ? proxyReg.serviceLease : null;
>> +            if( svcLease != null ) {
>>                try {
>> -                    proxyReg.serviceLease.cancel();
>> +                    svcLease.cancel();
>>                } catch (Exception e) { /*ignore*/ }
>>            }//endif
>>            logger.finest("JoinManager - DiscardProxyTask completed");
>> @@ -1140,31 +1145,34 @@
>>        /** The <code>ProxyRegTask</code> that instantiated this
>>         *  <code>ProxyReg</code>.
>>         */
>> -        public ProxyRegTask proxyRegTask;
>> +        volatile ProxyRegTask proxyRegTask;
>>        /** The <i>prepared</i> proxy to the lookup service referenced by
>>         *  this class, and with which this join manager's service will be
>>         *  registered.
>>         */
>> -	public ServiceRegistrar proxy;
>> +	final ServiceRegistrar proxy;
>>        /** The <i>prepared</i> registration proxy returned by this class'
>>         *  associated lookup service when this join manager registers its
>>         *  associated service.
>> +         * 
>> +         * Access to reference synchronized on joinSet, but not referent
>> +         * as it has foreign remote methods.
>>         */
>> -	public ServiceRegistration srvcRegistration = null;
>> +	ServiceRegistration srvcRegistration = null;
>>        /* The <i>prepared</i> proxy to the lease on the registration of this
>>         * join manager's service with the this class' associated lookup
>>         * service.
>>         */
>> -	public Lease serviceLease = null;
>> +	volatile Lease serviceLease = null;
>>        /** The set of sub-tasks that are to be executed in order for the
>>         *  lookup service associated with the current instance of this class.
>>         */
>> -        public List taskList = new ArrayList(1);
>> +        final List taskList = new ArrayList(1);
>>        /** The instance of <code>DiscLeaseListener</code> that is registered
>>         *  with the lease renewal manager that handles the lease of this join
>>         *  manger's service.
>>         */
>> -	private DiscLeaseListener dListener = new DiscLeaseListener();
>> +	private final DiscLeaseListener dListener = new DiscLeaseListener();
>> 
>>        /** Constructor that associates this class with the lookup service
>>         *  referenced in the given <code>ProxyReg</code> parameter.
>> @@ -1236,19 +1244,19 @@
>>                throw e; //rethrow the exception since proxy may be unusable
>>            }
>>            /* Retrieve and prepare the proxy to the service lease */
>> -            serviceLease = tmpSrvcRegistration.getLease();
>> +            Lease svcLease = tmpSrvcRegistration.getLease();
>>            try {
>> -                serviceLease = 
>> -                       (Lease)serviceLeasePreparer.prepareProxy(serviceLease);
>> +                this.serviceLease = 
>> +                       (Lease)serviceLeasePreparer.prepareProxy(svcLease);
>>                logger.finest("JoinManager - service lease proxy prepared");
>>            } catch(Exception e) {
>> 		LogUtil.logThrow(logger, Level.WARNING, ProxyReg.class,
>> 		    	"register", "JoinManager - failure during " +
>> 		    	"preparation of service lease proxy: {0}",
>> -		    	new Object[] { serviceLease }, e);
>> +		    	new Object[] { svcLease }, e);
>>                throw e; //rethrow the exception since proxy may be unusable
>>            }
>> -            leaseRenewalMgr.renewUntil(serviceLease, Lease.FOREVER,
>> +            leaseRenewalMgr.renewUntil(svcLease, Lease.FOREVER,
>>                                       renewalDuration, dListener);
>>            ServiceID tmpID = null;
>>            synchronized(joinSet) {
>> @@ -1272,7 +1280,11 @@
>>         *  addition to that service's current set of attributes.
>>         */
>>        public void addAttributes(Entry[] attSet) throws Exception {
>> -            srvcRegistration.addAttributes(attSet);
>> +            ServiceRegistration sr;
>> +            synchronized (joinSet){
>> +                sr = srvcRegistration;
>> +            }
>> +            sr.addAttributes(attSet);
>> 	}//end ProxyReg.addAttributes
>> 
>>        /** With respect to the lookup service referenced in this class
>> @@ -1285,7 +1297,11 @@
>>        public void modifyAttributes(Entry[] templ, Entry[] attSet)
>>                                                             throws Exception
>>        {
>> -            srvcRegistration.modifyAttributes(templ, attSet);
>> +            ServiceRegistration sr;
>> +            synchronized (joinSet){
>> +               sr = srvcRegistration;
>> +            }
>> +            sr.modifyAttributes(templ, attSet);
>> 	}//end ProxyReg.modifyAttributes		    
>> 
>>        /** With respect to the lookup service referenced in this class
>> @@ -1294,7 +1310,11 @@
>>         *  set of attributes.
>>         */
>>        public void setAttributes(Entry[] attSet) throws Exception {
>> -            srvcRegistration.setAttributes(attSet);
>> +            ServiceRegistration sr;
>> +            synchronized (joinSet){
>> +               sr = srvcRegistration;
>> +            }
>> +            sr.setAttributes(attSet);
>> 	}//end ProxyReg.setAttributes
>> 
>>        /** Convenience method that encapsulates appropriate behavior when
>> @@ -1432,7 +1452,7 @@
>>     *  which each task is associated). This field contains the value of
>>     *  the sequence number assigned to the most recently created task.
>>     */
>> -    private int taskSeqN = 0;
>> +    private int taskSeqN = 0; // access sync on taskList
>>    /** Task manager for the various tasks executed by this join manager.
>>     *  On the first attempt to execute any task is managed by this
>>     *  <code>TaskManager</code> so that the number of concurrent threads
>> @@ -1442,9 +1462,9 @@
>>     *  "backoff strategy") - the re-execution of each failed task in this
>>     *  <code>TaskManager</code>.
>>     */
>> -    private TaskManager taskMgr;
>> +    private final TaskManager taskMgr;
>>    /** Maximum number of times a failed task is allowed to be re-executed. */
>> -    private int maxNRetries = 6;
>> +    private final int maxNRetries;
>>    /** Wakeup manager for the various tasks executed by this join manager.
>>     *  After an initial failure of any task executed by this join manager,
>>     *  the failed task is managed by this <code>WakeupManager</code>; which
>> @@ -1456,22 +1476,22 @@
>>     *  join manager is requested, all tasks scheduled for retry by this
>>     *  wakeup manager can be cancelled.
>>     */
>> -    private WakeupManager wakeupMgr;
>> +    private final WakeupManager wakeupMgr;
>>    /** Contains the reference to the service that is to be registered with
>>     *  all of the desired lookup services referenced by <code>discMgr</code>.
>>     */
>> -    private ServiceItem serviceItem;
>> +    private final ServiceItem serviceItem;
>>    /** Contains the attributes with which to associate the service in each
>>     *  of the lookup services with which this join manager registers the
>>     *  service.
>>     */
>> -    private Entry[] lookupAttr = null;
>> +    private Entry[] lookupAttr = null; // access sync on joinSet
>>    /** Contains the listener -- instantiated by the entity that constructs
>>     *  this join manager -- that will receive an event containing the
>>     *  service ID assigned to this join manager's service by one of the
>>     *  lookup services with which that service is registered.
>>     */
>> -    private ServiceIDListener callback;
>> +    private final ServiceIDListener callback;
>>    /** Contains elements of type <code>ProxyReg</code> where each element
>>     *  references a proxy to one of the lookup services with which this
>>     *  join manager's service is registered.
>> @@ -1480,22 +1500,22 @@
>>    /** Contains the discovery manager that discovers the lookup services
>>     *  with which this join manager will register its associated service.
>>     */
>> -    private DiscoveryManagement discMgr = null;
>> +    private final DiscoveryManagement discMgr;
>>    /** Contains the discovery listener registered by this join manager with
>>     *  the discovery manager so that this join manager is notified whenever
>>     *  one of the desired lookup services is discovered or discarded.
>>     */
>> -    private DiscMgrListener discMgrListener = new DiscMgrListener();
>> +    private final DiscMgrListener discMgrListener ;
>>    /** Flag that indicate whether the discovery manager employed by this
>>     *  join manager was created by this join manager itself, or by the
>>     *  entity that constructed this join manager.
>>     */
>> -    private boolean bCreateDiscMgr = false;
>> +    private final boolean bCreateDiscMgr;
>>    /** Contains the lease renewal manager that renews all of the leases
>>     *  this join manager's service holds with each lookup service with which
>>     *  it has been registered.
>>     */
>> -    private LeaseRenewalManager leaseRenewalMgr = null;
>> +    private final LeaseRenewalManager leaseRenewalMgr;
>>    /** The value to use as the <code>renewDuration</code> parameter
>>     *  when invoking the lease renewal manager's <code>renewUntil</code>
>>     *  method to add a service lease to manage. This value represents,
>> @@ -1505,22 +1525,22 @@
>>     *  is up, and lease expirations will occur sooner when the service
>>     *  goes down.
>>     */
>> -    private long renewalDuration = Lease.FOREVER;
>> +    private final long renewalDuration;
>>    /** Flag that indicates if this join manager has been terminated. */
>> -    private volatile boolean bTerminated = false;
>> +    private boolean bTerminated = false; // All access sync on this.
>>    /* Preparer for the proxies to the lookup services that are discovered
>>     * and used by this utility.
>>     */
>> -    private ProxyPreparer registrarPreparer;
>> +    private final ProxyPreparer registrarPreparer;
>>    /* Preparer for the proxies to the registrations returned to this utility
>>     * upon registering the service with each discovered lookup service.
>>     */
>> -    private ProxyPreparer registrationPreparer;
>> +    private final ProxyPreparer registrationPreparer;
>>    /* Preparer for the proxies to the leases returned to this utility through
>>     * the registrations with each discovered lookup service with which this
>>     * utility has registered the service.
>>     */
>> -    private ProxyPreparer serviceLeasePreparer;
>> +    private final ProxyPreparer serviceLeasePreparer;
>> 
>>    /** 
>>     * Constructs an instance of this class that will register the given
>> @@ -1619,11 +1639,8 @@
>> 			DiscoveryManagement discoveryMgr,
>> 			LeaseRenewalManager leaseMgr)    throws IOException
>>    {
>> -        discMgr = discoveryMgr;
>> -        try {
>> -           createJoinManager(null, serviceProxy, attrSets, callback, leaseMgr,
>> -                             EmptyConfiguration.INSTANCE);
>> -        } catch(ConfigurationException e) { /* swallow this exception */ }
>> +           this(serviceProxy, attrSets, null, callback, 
>> +                 getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy));
>>    }//end constructor
>> 
>>    /** 
>> @@ -1737,9 +1754,10 @@
>>                        Configuration config)
>>                                    throws IOException, ConfigurationException
>>    {
>> -        discMgr = discoveryMgr;
>> -        createJoinManager(null, serviceProxy, attrSets,
>> -                          callback, leaseMgr, config);
>> +        
>> +        this(serviceProxy, attrSets, null, callback, 
>> +            getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
>> +        );
>>    }//end constructor
>> 
>>    /** 
>> @@ -1797,12 +1815,9 @@
>> 			DiscoveryManagement discoveryMgr,
>> 			LeaseRenewalManager leaseMgr)    throws IOException
>>    {
>> -        discMgr = discoveryMgr;
>> -        try {
>> -           createJoinManager(serviceID, serviceProxy, attrSets,
>> -                             (ServiceIDListener)null, leaseMgr,
>> -                             EmptyConfiguration.INSTANCE);
>> -        } catch(ConfigurationException e) { /* swallow this exception */ }
>> +       this(serviceProxy, attrSets, serviceID, null, 
>> +             getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy)
>> +       );
>>    }//end constructor
>> 
>>    /** 
>> @@ -1877,9 +1892,9 @@
>>                        Configuration config)
>>                                    throws IOException, ConfigurationException
>>    {
>> -        discMgr = discoveryMgr;
>> -        createJoinManager(serviceID, serviceProxy, attrSets,
>> -                          (ServiceIDListener)null, leaseMgr, config);
>> +        this(serviceProxy, attrSets, serviceID, null, 
>> +             getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
>> +       );
>>    }//end constructor
>> 
>>    /** 
>> @@ -2464,44 +2479,113 @@
>>        replaceRegistrationDo(serviceProxy, attrSets, true);
>>    }//end replaceRegistration
>> 
>> -    /** Convenience method invoked by the constructors of this class that
>> -     *  uses the given <code>Configuration</code> to initialize the current
>> -     *  instance of this utility, and initiates all join processing for
>> -     *  the given parameters. This method handles the various configurations
>> -     *  allowed by the different constructors.
>> +    private static class Conf{
>> +        ProxyPreparer registrarPreparer;
>> +        ProxyPreparer registrationPreparer;
>> +        ProxyPreparer serviceLeasePreparer;
>> +        TaskManager taskManager;
>> +        WakeupManager wakeupManager;
>> +        Integer maxNretrys;
>> +        LeaseRenewalManager leaseRenewalManager;
>> +        Long renewalDuration;
>> +        DiscoveryManagement discoveryMgr;
>> +        boolean bcreateDisco;
>> +        
>> +        Conf (  ProxyPreparer registrarPreparer,
>> +                ProxyPreparer registrationPreparer,
>> +                ProxyPreparer serviceLeasePreparer,
>> +                TaskManager taskManager,
>> +                WakeupManager wakeupManager,
>> +                Integer maxNretrys,
>> +                LeaseRenewalManager leaseRenewalManager,
>> +                Long renewalDuration,
>> +                DiscoveryManagement discoveryMgr,
>> +                boolean bcreateDisco)
>> +        {
>> +            this.registrarPreparer = registrarPreparer;
>> +            this.registrationPreparer = registrationPreparer;
>> +            this.serviceLeasePreparer = serviceLeasePreparer;
>> +            this.taskManager = taskManager;
>> +            this.wakeupManager = wakeupManager;
>> +            this.maxNretrys = maxNretrys;
>> +            this.leaseRenewalManager = leaseRenewalManager;
>> +            this.renewalDuration = renewalDuration;
>> +            this.discoveryMgr = discoveryMgr;
>> +            this.bcreateDisco = bcreateDisco;
>> +        }
>> +    }
>> +    
>> +    /**
>> +     * This method is for constructors that use an empty configuration.
>> +     * 
>> +     * @param config
>> +     * @param leaseMgr
>> +     * @param discoveryMgr
>> +     * @param serviceProxy
>> +     * @return
>> +     * @throws IOException
>> +     * @throws NullPointerException
>> +     * @throws IllegalArgumentException 
>>     */
>> -    private void createJoinManager(ServiceID serviceID, 
>> -                                   Object serviceProxy,
>> -                                   Entry[] attrSets, 
>> -                                   ServiceIDListener callback,
>> +    private static Conf getConf(    Configuration config,
>>                                   LeaseRenewalManager leaseMgr,
>> -                                   Configuration config) 
>> -                                    throws IOException, ConfigurationException
>> +                                    DiscoveryManagement discoveryMgr,
>> +                                    Object serviceProxy) 
>> +            throws IOException, NullPointerException, IllegalArgumentException {
>> +        try {
>> +            return getConfig(config, leaseMgr, discoveryMgr, serviceProxy);
>> +        } catch (ConfigurationException e){
>> +            throw new IOException("Configuration problem during construction", e);
>> +        }
>> +    }
>> +    
>> +    /**
>> +     * Gets the configuration and throws any exceptions.
>> +     * 
>> +     * This static method guards against finalizer attacks and allows fields
>> +     * to be final.
>> +     * 
>> +     * @param config
>> +     * @param leaseMgr
>> +     * @param discoveryMgr
>> +     * @param serviceProxy
>> +     * @return
>> +     * @throws IOException
>> +     * @throws ConfigurationException
>> +     * @throws NullPointerException
>> +     * @throws IllegalArgumentException 
>> +     */
>> +    private static Conf getConfig(  Configuration config,
>> +                                    LeaseRenewalManager leaseMgr, 
>> +                                    DiscoveryManagement discoveryMgr,
>> +                                    Object serviceProxy) 
>> +            throws IOException, ConfigurationException, NullPointerException,
>> +            IllegalArgumentException 
>>    {
>> 	if(!(serviceProxy instanceof java.io.Serializable)) {
>>            throw new IllegalArgumentException
>>                                       ("serviceProxy must be Serializable");
>> 	}//endif
>> -
>>        /* Retrieve configuration items if applicable */
>>        if(config == null)  throw new NullPointerException("config is null");
>>        /* Proxy preparers */
>> -        registrarPreparer = (ProxyPreparer)config.getEntry
>> +        ProxyPreparer registrarPreparer = (ProxyPreparer)config.getEntry
>>                                                   (COMPONENT_NAME,
>>                                                    "registrarPreparer",
>>                                                    ProxyPreparer.class,
>>                                                    new BasicProxyPreparer());
>> -        registrationPreparer = (ProxyPreparer)config.getEntry
>> +        ProxyPreparer registrationPreparer = (ProxyPreparer)config.getEntry
>>                                                   (COMPONENT_NAME,
>>                                                    "registrationPreparer",
>>                                                    ProxyPreparer.class,
>>                                                    new BasicProxyPreparer());
>> -        serviceLeasePreparer = (ProxyPreparer)config.getEntry
>> +        ProxyPreparer serviceLeasePreparer = (ProxyPreparer)config.getEntry
>>                                                   (COMPONENT_NAME,
>>                                                    "serviceLeasePreparer",
>>                                                    ProxyPreparer.class,
>>                                                    new BasicProxyPreparer());
>>        /* Task manager */
>> +        TaskManager taskMgr;
>>        try {
>>            taskMgr = (TaskManager)config.getEntry(COMPONENT_NAME,
>>                                                   "taskManager",
>> @@ -2510,6 +2594,7 @@
>>            taskMgr = new TaskManager(MAX_N_TASKS,(15*1000),1.0f);
>>        }
>>        /* Wakeup manager */
>> +        WakeupManager wakeupMgr;
>>        try {
>>            wakeupMgr = (WakeupManager)config.getEntry(COMPONENT_NAME,
>>                                                       "wakeupManager",
>> @@ -2519,57 +2604,84 @@
>>                                    (new WakeupManager.ThreadDesc(null,true));
>>        }
>>        /* Max number of times to re-schedule tasks in thru wakeup manager */
>> -        maxNRetries = ((Integer)config.getEntry
>> +        Integer maxNRetries = ((Integer)config.getEntry
>>                                        (COMPONENT_NAME,
>>                                         "wakeupRetries",
>>                                         int.class,
>> -                                         Integer.valueOf(maxNRetries))).intValue();
>> -        if(attrSets == null) {
>> -            lookupAttr = new Entry[0];
>> -        } else {
>> -            attrSets = (Entry[])attrSets.clone();
>> -            LookupAttributes.check(attrSets,false);//null elements NOT ok
>> -            lookupAttr = attrSets;
>> -        }//endif
>> -	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
>> +                                         Integer.valueOf(6))).intValue();
>>        /* Lease renewal manager */
>> -        leaseRenewalMgr = leaseMgr;
>> -	if(leaseRenewalMgr == null) {
>> +	if(leaseMgr == null) {
>>            try {
>> -                leaseRenewalMgr = (LeaseRenewalManager)config.getEntry
>> +                leaseMgr = (LeaseRenewalManager)config.getEntry
>>                                                  (COMPONENT_NAME,
>>                                                   "leaseManager",
>>                                                   LeaseRenewalManager.class);
>>            } catch(NoSuchEntryException e) { /* use default */
>> -                leaseRenewalMgr = new LeaseRenewalManager(config);
>> +                leaseMgr = new LeaseRenewalManager(config);
>>            }
>>        }//endif
>> -        renewalDuration = ((Long)config.getEntry
>> +        Long renewalDuration = ((Long)config.getEntry
>>                                      (COMPONENT_NAME,
>>                                       "maxLeaseDuration",
>>                                       long.class,
>> -                                       Long.valueOf(renewalDuration))).longValue();
>> +                                       Long.valueOf(Lease.FOREVER))).longValue();
>>        if( (renewalDuration == 0) || (renewalDuration < Lease.ANY) ) {
>>            throw new ConfigurationException("invalid configuration entry: "
>>                                             +"renewalDuration ("
>>                                             +renewalDuration+") must be "
>>                                             +"positive or Lease.ANY");
>>        }//endif
>> -	this.callback = callback;
>>        /* Discovery manager */
>> -	if(discMgr == null) {
>> +        boolean bCreateDiscMgr = false;
>> +	if(discoveryMgr == null) {
>> 	    bCreateDiscMgr = true;
>>            try {
>> -                discMgr = (DiscoveryManagement)config.getEntry
>> +                discoveryMgr = (DiscoveryManagement)config.getEntry
>>                                                 (COMPONENT_NAME,
>>                                                  "discoveryManager",
>>                                                  DiscoveryManagement.class);
>>            } catch(NoSuchEntryException e) { /* use default */
>> -                discMgr = new LookupDiscoveryManager
>> +                discoveryMgr = new LookupDiscoveryManager
>>                                     (new String[] {""}, null, null, config);
>>            }
>> 	}//endif
>> -	discMgr.addDiscoveryListener(discMgrListener);
>> +        return new Conf(registrarPreparer, registrationPreparer, serviceLeasePreparer,
>> +                taskMgr, wakeupMgr, maxNRetries, leaseMgr, renewalDuration,
>> +                discoveryMgr, bCreateDiscMgr);
>> +    }
>> +    
>> +    /** Convenience method invoked by the constructors of this class that
>> +     *  uses the given <code>Configuration</code> to initialize the current
>> +     *  instance of this utility, and initiates all join processing for
>> +     *  the given parameters. This method handles the various configurations
>> +     *  allowed by the different constructors.
>> +     */
>> +    private JoinManager(Object serviceProxy,
>> +                                   Entry[] attrSets, ServiceID serviceID, 
>> +                                   ServiceIDListener callback, Conf conf)
>> +    {
>> +	registrarPreparer = conf.registrarPreparer;
>> +        registrationPreparer = conf.registrationPreparer;
>> +        serviceLeasePreparer = conf.serviceLeasePreparer;
>> +        taskMgr = conf.taskManager;
>> +        wakeupMgr = conf.wakeupManager;
>> +        maxNRetries = conf.maxNretrys;
>> +        leaseRenewalMgr = conf.leaseRenewalManager;
>> +        renewalDuration = conf.renewalDuration;
>> +        bCreateDiscMgr = conf.bcreateDisco;
>> +        DiscMgrListener discMgrListen = new DiscMgrListener();
>> +        if(attrSets == null) {
>> +            lookupAttr = new Entry[0];
>> +        } else {
>> +            attrSets = attrSets.clone();
>> +            LookupAttributes.check(attrSets,false);//null elements NOT ok
>> +            lookupAttr = attrSets;
>> +        }//endif
>> +	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
>> +	this.callback = callback;
>> +	conf.discoveryMgr.addDiscoveryListener(discMgrListen);
>> +        discMgr = conf.discoveryMgr;
>> +        discMgrListener = discMgrListen;
>>    }//end createJoinManager
>> 
>>    /** For the given lookup service proxy, searches the <code>joinSet</code>
>> @@ -2623,9 +2735,10 @@
>>                }//end loop
>>                /* Interrupt all active tasks, prepare taskMgr for GC. */
>>                taskMgr.terminate();
>> -                taskMgr = null;
>> +        // Too lazy to put out the trash.
>> +//                taskMgr = null;
>>            }//end sync(taskMgr)
>> -            wakeupMgr = null;
>> +//            wakeupMgr = null;
>>        }//end sync(wakeupMgr)
>>    }//end terminateTaskMgr
>> 
>> Index: src/org/apache/river/api/security/URIGrant.java
>> --- src/org/apache/river/api/security/URIGrant.java Base (BASE)
>> +++ src/org/apache/river/api/security/URIGrant.java Locally Modified (Based On LOCAL)
>> @@ -135,12 +135,17 @@
>>        if (url == null ) return false;
>>        Uri implied = null;
>>        try {
>> -            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
>> -        } catch (PrivilegedActionException ex) {
>> -            Exception cause = ex.getException();
>> -            cause.printStackTrace(System.err);
>> -            return false;
>> +            implied = Uri.urlToUri(url);
>> +        } catch (URISyntaxException ex) {
>> +            Logger.getLogger(URIGrant.class.getName()).log(Level.SEVERE, null, ex);
>>        }
>> +//        try {
>> +//            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
>> +//        } catch (PrivilegedActionException ex) {
>> +//            Exception cause = ex.getException();
>> +//            cause.printStackTrace(System.err);
>> +//            return false;
>> +//        }
>>        for (int i = 0; i<l ; i++){
>>            if (uris[i].implies(implied)) return true;
>>        }
> 


Re: Indefinite hang - no progress while in loop liveness failure

Posted by Gregg Wonderly <ge...@cox.net>.
Because pending is accessed in that method (isCompleted), and it is non-volatile, and the method is not synchronized, all bets are off on predictable behavior.

Gregg Wonderly

On Apr 14, 2013, at 3:16 PM, Peter Firmstone <ji...@zeus.net.au> wrote:

> Gregg,
> 
> You are so right, I've just spent the weekend trying to fix an unrelated test, fixing one problem reveals another.
> 
> The patch (attached) attempts to fix some synchronization issues with Mahalo, this patch needs to be applied against qa-refactoring in skunk.
> 
> These two tests hang indefinitely:
> 
> com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
> 
> com.sun.jini.test.impl.mahalo.PrepareAndCommitExceptionTest4.td  (Thread dump for this test appended).
> 
> 2013-04-15 05:53:48
> Full thread dump Java HotSpot(TM) Server VM (20.5-b03 mixed mode):
> 
> "RMI TCP Connection(332)-10.1.1.2" daemon prio=3 tid=0x007fd800 nid=0x6a runnable [0xb517f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.SocketInputStream.socketRead0(Native Method)
>   at java.net.SocketInputStream.read(SocketInputStream.java:129)
>   at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>   at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>   - locked <0xe66ec2e0> (a java.io.BufferedInputStream)
>   at java.io.FilterInputStream.read(FilterInputStream.java:66)
>   at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>   at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>   at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - <0xe645f1d8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
> 
> "(JSK) mux request dispatch" daemon prio=3 tid=0x01013000 nid=0x33 runnable [0xb467d000]
>  java.lang.Thread.State: RUNNABLE
>   at com.sun.jini.mahalo.AbortJob.computeResult(AbortJob.java:284)
>   - locked <0xbb8a2c10> (a com.sun.jini.mahalo.AbortJob)
>   at com.sun.jini.mahalo.TxnManagerTransaction.abort(TxnManagerTransaction.java:1034)
>   - locked <0xbb8a2c60> (a java.lang.Object)
>   at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:795)
>   at com.sun.jini.mahalo.TxnManagerImpl.abort(TxnManagerImpl.java:754)
>   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>   at java.lang.reflect.Method.invoke(Method.java:597)
>   at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>   at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>   at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>   at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>   at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>   at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>   at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>   at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>   at java.security.AccessController.doPrivileged(Native Method)
>   at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>   at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>   at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>   at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>   at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>   at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>   at java.security.AccessController.doPrivileged(Native Method)
>   at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) mux reader" daemon prio=3 tid=0x01011400 nid=0x32 runnable [0xb477f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.SocketInputStream.socketRead0(Native Method)
>   at java.net.SocketInputStream.read(SocketInputStream.java:129)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) mux reader" daemon prio=3 tid=0x005b0400 nid=0x31 runnable [0xb487f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.SocketInputStream.socketRead0(Native Method)
>   at java.net.SocketInputStream.read(SocketInputStream.java:129)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) mux writer" daemon prio=3 tid=0x005af400 nid=0x30 in Object.wait() [0xb497f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8a6d20> (a java.lang.Object)
>   at java.lang.Object.wait(Object.java:485)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>   - locked <0xbb8a6d20> (a java.lang.Object)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) mux writer" daemon prio=3 tid=0x005ae000 nid=0x2f in Object.wait() [0xb4a7f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8aad00> (a java.lang.Object)
>   at java.lang.Object.wait(Object.java:485)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>   - locked <0xbb8aad00> (a java.lang.Object)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) ConnectionManager.Reaper" daemon prio=3 tid=0x007ff000 nid=0x2c waiting on condition [0xb4d7f000]
>  java.lang.Thread.State: TIMED_WAITING (sleeping)
>   at java.lang.Thread.sleep(Native Method)
>   at net.jini.jeri.connection.ConnectionManager$Reaper.run(ConnectionManager.java:597)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) mux request dispatch" daemon prio=3 tid=0x006a0800 nid=0x2a in Object.wait() [0xb4f7d000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8aaf10> (a java.lang.Object)
>   at java.lang.Object.wait(Object.java:485)
>   at com.sun.jini.jeri.internal.mux.Session$MuxInputStream.read(Session.java:853)
>   - locked <0xbb8aaf10> (a java.lang.Object)
>   at net.jini.jeri.connection.ConnectionManager$Outbound$Input.read(ConnectionManager.java:550)
>   at net.jini.jeri.BasicObjectEndpoint.executeCall(BasicObjectEndpoint.java:410)
>   at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:806)
>   at net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
>   at net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
>   at $Proxy0.abort(Unknown Source)
>   at com.sun.jini.mahalo.TxnMgrProxy.abort(TxnMgrProxy.java:146)
>   at net.jini.core.transaction.server.ServerTransaction.abort(ServerTransaction.java:113)
>   at com.sun.jini.mahalo.TxnManagerTransaction.doAbort(TxnManagerTransaction.java:1134)
>   at com.sun.jini.mahalo.TxnManagerTransaction.commit(TxnManagerTransaction.java:763)
>   at com.sun.jini.mahalo.TxnManagerImpl.commit(TxnManagerImpl.java:712)
>   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>   at java.lang.reflect.Method.invoke(Method.java:597)
>   at net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
>   at net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
>   at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:491)
>   at net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
>   at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:488)
>   at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
>   at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:464)
>   at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
>   at java.security.AccessController.doPrivileged(Native Method)
>   at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:461)
>   at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:426)
>   at com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
>   at net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
>   at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
>   at com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
>   at java.security.AccessController.doPrivileged(Native Method)
>   at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) mux reader" daemon prio=3 tid=0x003bfc00 nid=0x26 runnable [0xb537f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.SocketInputStream.socketRead0(Native Method)
>   at java.net.SocketInputStream.read(SocketInputStream.java:129)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$1.read(StreamConnectionIO.java:358)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Reader.run(StreamConnectionIO.java:265)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) mux writer" daemon prio=3 tid=0x00984400 nid=0x25 in Object.wait() [0xb547f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8bad70> (a java.lang.Object)
>   at java.lang.Object.wait(Object.java:485)
>   at com.sun.jini.jeri.internal.mux.StreamConnectionIO$Writer.run(StreamConnectionIO.java:171)
>   - locked <0xbb8bad70> (a java.lang.Object)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "event listener notification" daemon prio=3 tid=0x00483000 nid=0x23 in Object.wait() [0xb567f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8bb778> (a java.util.LinkedList)
>   at java.lang.Object.wait(Object.java:485)
>   at net.jini.discovery.LookupDiscovery$Notifier.run(LookupDiscovery.java:920)
>   - locked <0xbb8bb778> (a java.util.LinkedList)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "multicast announcement timer" daemon prio=3 tid=0x00ade000 nid=0x22 waiting on condition [0xb577f000]
>  java.lang.Thread.State: TIMED_WAITING (sleeping)
>   at java.lang.Thread.sleep(Native Method)
>   at net.jini.discovery.LookupDiscovery$AnnouncementTimerThread.run(LookupDiscovery.java:1434)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "multicast discovery announcement listener" daemon prio=3 tid=0x00adcc00 nid=0x21 runnable [0xb587f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.PlainDatagramSocketImpl.peekData(Native Method)
>   - locked <0xbb8bdab8> (a java.net.PlainDatagramSocketImpl)
>   at java.net.DatagramSocket.receive(DatagramSocket.java:675)
>   - locked <0xbb8bfae8> (a java.net.DatagramPacket)
>   - locked <0xbb8bda80> (a java.net.MulticastSocket)
>   at net.jini.discovery.LookupDiscovery$AnnouncementListener.run(LookupDiscovery.java:1205)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "settleThread" daemon prio=3 tid=0x00669c00 nid=0x1e in Object.wait() [0xb5b7f000]
>  java.lang.Thread.State: TIMED_WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
>   at com.sun.jini.mahalo.TxnManagerImpl.settleTxns(TxnManagerImpl.java:885)
>   - locked <0xbb8a2b38> (a com.sun.jini.mahalo.TransientMahaloImpl)
>   at com.sun.jini.mahalo.TxnManagerImpl.access$100(TxnManagerImpl.java:117)
>   at com.sun.jini.mahalo.TxnManagerImpl$2.run(TxnManagerImpl.java:331)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) KeepAlive" prio=3 tid=0x005cc800 nid=0x1d waiting on condition [0xb5c7f000]
>  java.lang.Thread.State: TIMED_WAITING (sleeping)
>   at java.lang.Thread.sleep(Native Method)
>   at com.sun.jini.jeri.internal.runtime.JvmLifeSupport$2.run(JvmLifeSupport.java:133)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) Reaper" daemon prio=3 tid=0x005cc000 nid=0x1c in Object.wait() [0xb5d7f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
>   at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>   - locked <0xbb8a7548> (a java.lang.ref.ReferenceQueue$Lock)
>   at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>   at com.sun.jini.jeri.internal.runtime.ImplRefManager$Reaper.run(ImplRefManager.java:426)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "(JSK) TcpServerEndpoint.LH[ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=36713]] accept loop" daemon prio=3 tid=0x005ce400 nid=0x1b runnable [0xb5e7f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.PlainSocketImpl.socketAccept(Native Method)
>   at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>   - locked <0xbb8b8708> (a java.net.SocksSocketImpl)
>   at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>   at java.net.ServerSocket.accept(ServerSocket.java:430)
>   at net.jini.jeri.tcp.TcpServerEndpoint$LH.executeAcceptLoop(TcpServerEndpoint.java:797)
>   at net.jini.jeri.tcp.TcpServerEndpoint$LH.access$400(TcpServerEndpoint.java:735)
>   at net.jini.jeri.tcp.TcpServerEndpoint$LH$1.run(TcpServerEndpoint.java:767)
>   at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:143)
>   at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:177)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "RMI TCP Connection(331)-10.1.1.2" daemon prio=3 tid=0x003a8c00 nid=0x1a runnable [0xb5f7f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.SocketInputStream.socketRead0(Native Method)
>   at java.net.SocketInputStream.read(SocketInputStream.java:129)
>   at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
>   at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
>   - locked <0xe66b5280> (a java.io.BufferedInputStream)
>   at java.io.FilterInputStream.read(FilterInputStream.java:66)
>   at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:517)
>   at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
>   at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
>   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - <0xbb8c0420> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
> 
> "JMX server connection timeout 18" daemon prio=3 tid=0x005cf800 nid=0x19 in Object.wait() [0xb607f000]
>  java.lang.Thread.State: TIMED_WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8c0718> (a [I)
>   at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150)
>   - locked <0xbb8c0718> (a [I)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "RMI Scheduler(0)" daemon prio=3 tid=0x005d1400 nid=0x18 waiting on condition [0xb617f000]
>  java.lang.Thread.State: TIMED_WAITING (parking)
>   at sun.misc.Unsafe.park(Native Method)
>   - parking to wait for  <0xbb8a2178> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>   at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>   at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>   at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>   at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>   at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>   at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "DestroyJavaVM" prio=3 tid=0x00031800 nid=0x2 waiting on condition [0x00000000]
>  java.lang.Thread.State: RUNNABLE
> 
>  Locked ownable synchronizers:
>   - None
> 
> "Thread-1" prio=3 tid=0x004be800 nid=0x17 runnable [0xb627f000]
>  java.lang.Thread.State: TIMED_WAITING (parking)
>   at sun.misc.Unsafe.park(Native Method)
>   - parking to wait for  <0xbb8c0cd0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
>   at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
>   at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
>   at java.util.concurrent.DelayQueue.take(DelayQueue.java:164)
>   at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:609)
>   at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:602)
>   at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:947)
>   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "GC Daemon" daemon prio=3 tid=0x0052dc00 nid=0x15 in Object.wait() [0xb647f000]
>  java.lang.Thread.State: TIMED_WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb8076b8> (a sun.misc.GC$LatencyLock)
>   at sun.misc.GC$Daemon.run(GC.java:100)
>   - locked <0xbb8076b8> (a sun.misc.GC$LatencyLock)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "RMI Reaper" prio=3 tid=0x00529800 nid=0x14 in Object.wait() [0xb657f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
>   at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>   - locked <0xbb800100> (a java.lang.ref.ReferenceQueue$Lock)
>   at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>   at sun.rmi.transport.ObjectTable$Reaper.run(ObjectTable.java:333)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "RMI TCP Accept-0" daemon prio=3 tid=0x002f5400 nid=0x13 runnable [0xb667f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.PlainSocketImpl.socketAccept(Native Method)
>   at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>   - locked <0xbb8001a8> (a java.net.SocksSocketImpl)
>   at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>   at java.net.ServerSocket.accept(ServerSocket.java:430)
>   at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>   at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "RMI TCP Accept-0" daemon prio=3 tid=0x002f4c00 nid=0x12 runnable [0xb677f000]
>  java.lang.Thread.State: RUNNABLE
>   at java.net.PlainSocketImpl.socketAccept(Native Method)
>   at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
>   - locked <0xbb803c98> (a java.net.SocksSocketImpl)
>   at java.net.ServerSocket.implAccept(ServerSocket.java:462)
>   at java.net.ServerSocket.accept(ServerSocket.java:430)
>   at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:34)
>   at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:369)
>   at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:341)
>   at java.lang.Thread.run(Thread.java:662)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "Attach Listener" daemon prio=3 tid=0x0020ac00 nid=0xf waiting on condition [0x00000000]
>  java.lang.Thread.State: RUNNABLE
> 
>  Locked ownable synchronizers:
>   - None
> 
> "Low Memory Detector" daemon prio=3 tid=0x00124000 nid=0xd runnable [0x00000000]
>  java.lang.Thread.State: RUNNABLE
> 
>  Locked ownable synchronizers:
>   - None
> 
> "C2 CompilerThread1" daemon prio=3 tid=0x00121000 nid=0xc waiting on condition [0x00000000]
>  java.lang.Thread.State: RUNNABLE
> 
>  Locked ownable synchronizers:
>   - None
> 
> "C2 CompilerThread0" daemon prio=3 tid=0x0011ec00 nid=0xb waiting on condition [0x00000000]
>  java.lang.Thread.State: RUNNABLE
> 
>  Locked ownable synchronizers:
>   - None
> 
> "Signal Dispatcher" daemon prio=3 tid=0x0011d000 nid=0xa runnable [0x00000000]
>  java.lang.Thread.State: RUNNABLE
> 
>  Locked ownable synchronizers:
>   - None
> 
> "Finalizer" daemon prio=3 tid=0x0010c800 nid=0x9 in Object.wait() [0xb707f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
>   at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
>   - locked <0xbb804000> (a java.lang.ref.ReferenceQueue$Lock)
>   at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
>   at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "Reference Handler" daemon prio=3 tid=0x00107c00 nid=0x8 in Object.wait() [0xb717f000]
>  java.lang.Thread.State: WAITING (on object monitor)
>   at java.lang.Object.wait(Native Method)
>   - waiting on <0xbb804090> (a java.lang.ref.Reference$Lock)
>   at java.lang.Object.wait(Object.java:485)
>   at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
>   - locked <0xbb804090> (a java.lang.ref.Reference$Lock)
> 
>  Locked ownable synchronizers:
>   - None
> 
> "VM Thread" prio=3 tid=0x00104000 nid=0x7 runnable
> 
> "GC task thread#0 (ParallelGC)" prio=3 tid=0x00039000 nid=0x3 runnable
> 
> "GC task thread#1 (ParallelGC)" prio=3 tid=0x0003a800 nid=0x4 runnable
> 
> "GC task thread#2 (ParallelGC)" prio=3 tid=0x0003bc00 nid=0x5 runnable
> 
> "GC task thread#3 (ParallelGC)" prio=3 tid=0x0003d000 nid=0x6 runnable
> 
> "VM Periodic Task Thread" prio=3 tid=0x00136000 nid=0xe waiting on condition
> 
> JNI global references: 1404
> 
> # This patch file was generated by NetBeans IDE
> # Following Index: paths are relative to: /opt/src/River_Fixed/peterConcurrentPolicy
> # This patch can be applied using context Tools: Patch action on respective folder.
> # It uses platform neutral UTF-8 encoding and \n newlines.
> # Above lines and this line are ignored by the patching process.
> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td
> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Base (BASE)
> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest.td Locally Modified (Based On LOCAL)
> @@ -1,3 +1,6 @@
> include0=mahalo.properties
> testClass=PrepareAndCommitExceptionTest
> testCategories=txnmanager,txnmanager_impl
> +#testjvmargs=-Xdebug,\
> +#-Xrunjdwp:transport=dt_socket+,address=8000+,server=y+,suspend=y,\
> +#${testjvmargs}
> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java
> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Base (BASE)
> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.java Locally Modified (Based On LOCAL)
> @@ -44,15 +44,15 @@
>  */
> public class PrepareAndCommitExceptionTest2 extends TxnManagerTest {
> 
> -      class Clearer implements Runnable {
> -         TestParticipant part;
> +      static class Clearer implements Runnable {
> +         final TestParticipant part;
>          Clearer(TestParticipant part) {
>              this.part = part;
>          }
> 
>          public void run() {
>             try {
> -                Thread.sleep(10000);
> +                Thread.sleep(1000); // was 10 minutes, not necessary on modern hardware.
>             } catch (Exception e) {
>                 logger.log(Level.INFO, "Caught sleep exception -- ignoring: " + e);                                    
>             }
> @@ -94,7 +94,7 @@
>         t.start();
>         logger.log(Level.INFO, "Committing transaction");                        
>         try {
> -            cr.transaction.commit(60000);
> +            cr.transaction.commit(2000); // Was 60 minutes, didn't feel like waiting that long!
>             throw new TestException("ServerException not thrown");
>         } catch (ServerException se) {
>             logger.log(Level.INFO, "Caught expected exception: " + se);                                    
> Index: qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td
> --- qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Base (BASE)
> +++ qa/src/com/sun/jini/test/impl/mahalo/PrepareAndCommitExceptionTest2.td Locally Modified (Based On LOCAL)
> @@ -1,3 +1,4 @@
> include0=mahalo.properties
> testClass=PrepareAndCommitExceptionTest2
> testCategories=txnmanager,txnmanager_impl
> +# This test presently hangs, if the Clearer thread runs after the commit timeout, it doesn't occur.
> \ No newline at end of file
> Index: qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java
> --- qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Base (BASE)
> +++ qa/src/com/sun/jini/test/impl/mahalo/RandomStressTest.java Locally Modified (Based On LOCAL)
> @@ -68,11 +68,11 @@
>     private long sleep_time = SLEEP_TIME;
> 
>     // Another values.
> -    private TransactionManager mgr = null;
> +    private volatile TransactionManager mgr = null;
>     private TaskManager threadpool = null;
> -    private WakeupManager wakeupManager = null;
> -    private Random random;
> -    private long seed = 0;
> +    private volatile WakeupManager wakeupManager = null;
> +    private volatile Random random;
> +    private volatile long seed = 0;
> 
>     public Test construct(QAConfig sysConfig) throws Exception {
>         super.construct(sysConfig);
> Index: qa/src/com/sun/jini/test/share/TestParticipantImpl.java
> --- qa/src/com/sun/jini/test/share/TestParticipantImpl.java Base (BASE)
> +++ qa/src/com/sun/jini/test/share/TestParticipantImpl.java Locally Modified (Based On LOCAL)
> @@ -19,6 +19,8 @@
> package com.sun.jini.test.share;
> 
> import com.sun.jini.mahalo.*;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> import net.jini.core.transaction.*;
> import net.jini.core.transaction.server.*;
> 
> @@ -48,15 +50,16 @@
> 	       TransactionParticipant, TestParticipant, ProxyAccessor,
> 	       ServerProxyTrust
> {
> -    private String name;
> -    private BitSet behavior; 
> +    private final String name;
> +    private final BitSet behavior; 
>     private final Object lock2;
> -    private long crashcount;
> -    private ServerTransaction str;
> +    private volatile long crashcount; // atomic increment with lock2
> +    private volatile ServerTransaction str;
>     private static final long TENSECONDS = 1000 * 10;
>     private static final long THIRTYSECONDS = TENSECONDS *3;
>     private static final boolean DEBUG = true;
> -    private TransactionParticipant proxy;
> +    private volatile TransactionParticipant proxy = null;
> +    private Exporter exporter;
> 
>     public TestParticipantImpl() throws RemoteException {
> 	this(DEFAULT_NAME);
> @@ -68,7 +71,7 @@
> 	crashcount = System.currentTimeMillis();
> 	behavior   = new BitSet(OPERATION_COUNT);
> 	Configuration c = QAConfig.getConfig().getConfiguration();
> -	Exporter exporter = QAConfig.getDefaultExporter();
> +	exporter = QAConfig.getDefaultExporter();
> 	if (c instanceof com.sun.jini.qa.harness.QAConfiguration) {
> 	    try {
> 		exporter = (Exporter) c.getEntry("test",
> @@ -78,15 +81,28 @@
> 		throw new RemoteException("Configuration Error", e);
> 	    }
> 	}
> -	proxy = (TransactionParticipant)exporter.export(this);
> +        // Can't export here without this escaping.
>     }
> 
>     public Object getProxy() {
> +        if (proxy != null){
> 	return proxy;
> +        } else {
> +            synchronized (lock2){
> +                if (proxy != null) return proxy; // Don't export it twice.
> +                try {
> +                    proxy = (TransactionParticipant)exporter.export(this);
> +                    exporter = null;
> +                } catch (ExportException ex) {
> +                    // Nothing we can do
>     }
> +            }
> +        }
> +        return proxy; // May be null
> +    }
> 
>     public TrustVerifier getProxyVerifier() {
> -	return new BasicProxyTrustVerifier(proxy);
> +	return new BasicProxyTrustVerifier(getProxy());
>     }
> 
>     private boolean checkBit(int bit) {
> @@ -136,7 +152,7 @@
> 		System.out.println(name + ": joining");
> 	    }
> 
> -	    str.join(proxy, crashcount);
> +	    str.join((TransactionParticipant) getProxy(), crashcount);
> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
> 		    doTimeout(THIRTYSECONDS);
> @@ -157,7 +173,7 @@
> 		System.out.println(name + ": joining again");
> 	    }
> 
> -	    str.join(proxy, crashcount);
> +	    str.join((TransactionParticipant) getProxy(), crashcount);
> 
> 	    if(checkBit(OP_TIMEOUT_JOIN)) {
> 		if(checkBit(OP_TIMEOUT_VERYLONG)) {
> Index: qa/src/com/sun/jini/test/share/TxnManagerTest.java
> --- qa/src/com/sun/jini/test/share/TxnManagerTest.java Base (BASE)
> +++ qa/src/com/sun/jini/test/share/TxnManagerTest.java Locally Modified (Based On LOCAL)
> @@ -42,16 +42,20 @@
> {
>     protected static final boolean DEBUG = true;
> 
> -    TransactionManager[] mgrs = new TransactionManager[1];
> +    final TransactionManager[] mgrs = new TransactionManager[1];
> 
>     public TransactionManager manager() throws RemoteException {
> +        synchronized (mgrs){
> 	return (TransactionManager) mgrs[0];
>     }
> +    }
> 
>     protected void startTxnMgr() throws TestException {
> 	specifyServices(new Class[] {TransactionManager.class}); 
> +        synchronized (mgrs){
> 	mgrs[0]= (TransactionManager)services[0]; // prepared by specifyServices
>     }
> +    }
> 
>     public Test construct(QAConfig config) throws Exception {
>         super.construct(config);
> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java
> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Base (BASE)
> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/JavaSpaceTest.java Locally Modified (Based On LOCAL)
> @@ -192,7 +192,9 @@
>             if (trc == null) {
>                 throw new TestException("Null transaction has been obtained.");
>             }
> +            synchronized (txns){
>             txns.add(trc.transaction);
> +            }
>             return trc.transaction;
>         } catch (Exception e) {
>             throw new TestException("Could not create transaction.", e);
> Index: qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties
> --- qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Base (BASE)
> +++ qa/src/com/sun/jini/test/spec/javaspace/conformance/javaspace.properties Locally Modified (Based On LOCAL)
> @@ -15,8 +15,8 @@
> 
> # timeout2 must be greater than (timeout1 + instantTime)
> # it is recommended that timeout2 be greater than (timeout1 + 2*instantTime)
> -com.sun.jini.test.spec.javaspace.conformance.timeout1=24000
> -com.sun.jini.test.spec.javaspace.conformance.timeout2=48000
> +com.sun.jini.test.spec.javaspace.conformance.timeout1=20000
> +com.sun.jini.test.spec.javaspace.conformance.timeout2=40000
> 
> #  general round trip time expected to non-blocking operations.
> #  should be set to checkTime / 2. 
> Index: qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java
> --- qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Base (BASE)
> +++ qa/src/com/sun/jini/test/spec/txnmanager/AsynchAbortOnCommitTest.java Locally Modified (Based On LOCAL)
> @@ -80,11 +80,11 @@
>             while (true) {
>                 state = str.mgr.getState(str.id);
> 
> -                if (DEBUG) {
> -                    int st = state;
> -                    logger.log(Level.INFO, "state = "
> -                            + com.sun.jini.constants.TxnConstants.getName(st));
> -                }
> +//                if (DEBUG) {
> +//                    int st = state;
> +//                    logger.log(Level.FINEST, "state = "
> +//                            + com.sun.jini.constants.TxnConstants.getName(st));
> +//                }
> 
>                 if (state == COMMITTED) {
>                     break;
> Index: qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java
> --- qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Base (BASE)
> +++ qa/src/com/sun/jini/test/spec/txnmanager/CommitThread.java Locally Modified (Based On LOCAL)
> @@ -21,15 +21,16 @@
> 
> 
> class CommitThread extends Thread {
> -    long timeOut;
> -    Transaction tr;
> +    final long timeOut;
> +    final Transaction tr;
> 
>     public CommitThread(Transaction tr) {
>         this.tr = tr;
> +        timeOut = 0;
>     }
> 
>     public CommitThread(Transaction tr, long timeOut) {
> -        this(tr);
> +        this.tr = tr;
> 
>         if (timeOut < 0) {
>             throw new IllegalArgumentException("timeout must be non-negative");
> Index: src/com/sun/jini/collection/WeakTable.java
> --- src/com/sun/jini/collection/WeakTable.java Base (BASE)
> +++ src/com/sun/jini/collection/WeakTable.java Locally Modified (Based On LOCAL)
> @@ -52,16 +52,16 @@
>  */
> public class WeakTable {
>     /** The map of known objects.  */
> -    private HashMap		table = new HashMap();
> +    private final HashMap table;
> 
>     /** The queue of cleared SpaceProxy objects. */
> -    private ReferenceQueue	refQueue = new ReferenceQueue();
> +    private final ReferenceQueue refQueue;
> 
>     /** Print debug messages to this stream if not <code>null</code>. */
>     private static PrintStream		DEBUG = null;
> 
>     /** Object to call back when keys are collected */
> -    private KeyGCHandler handler = null;
> +    private final KeyGCHandler handler;
> 
>     /**
>      * Create a new WeakTable object to maintain the maps.
> @@ -72,6 +72,7 @@
> 
> 	table = new HashMap();
> 	refQueue = new ReferenceQueue();
> +        handler = null;
>     }
> 
>     /**
> @@ -79,7 +80,11 @@
>      * back the designated object when keys are collected.
>      */
>     public WeakTable(KeyGCHandler handler) {
> -	this();
> +        if (DEBUG != null)
> +	    DEBUG.println("Creating WeakTable");
> +
> +	table = new HashMap();
> +	refQueue = new ReferenceQueue();
> 	this.handler = handler;
>     }
> 
> Index: src/com/sun/jini/mahalo/AbortJob.java
> --- src/com/sun/jini/mahalo/AbortJob.java Base (BASE)
> +++ src/com/sun/jini/mahalo/AbortJob.java Locally Modified (Based On LOCAL)
> @@ -29,6 +29,7 @@
> import java.rmi.ConnectIOException;
> import java.rmi.AccessException;
> import java.rmi.ConnectException;
> +import java.util.Iterator;
> 
> import java.util.logging.Level;
> import java.util.logging.Logger;
> @@ -54,10 +55,10 @@
>  *
>  */
> public class AbortJob extends Job implements TransactionConstants {
> -    ServerTransaction tr;
> -    ClientLog log;
> -    ParticipantHandle[] handles;
> -    int maxtries = 5;
> +    final ServerTransaction tr;
> +    final ClientLog log;
> +    final ParticipantHandle[] handles;
> +    final int maxtries = 5;
>     static final Logger logger = TxnManagerImpl.participantLogger;
> 
>     /**
> @@ -272,13 +273,16 @@
> 	int tmp = 0;
> 	int count = 0;
> 
> -	checkresults:
> -	for (int i = 0; i < results.length; i++) {
> -	    tmp = ((Integer)results[i]).intValue();
> -
> -	    if (tmp == ABORTED)
> -		count++;
> +        synchronized (this){
> +            Iterator i = results.values().iterator();
> +            while (i.hasNext()){
> +                Object res = i.hasNext();
> +                if (res instanceof Integer){
> +                    tmp = ((Integer)res).intValue();
> +                    if (tmp == ABORTED) count++;
> 	}
> +            }
> +        }
> 
>         if (logger.isLoggable(Level.FINEST)) {
>             logger.log(Level.FINEST,
> Index: src/com/sun/jini/mahalo/AbortRecord.java
> --- src/com/sun/jini/mahalo/AbortRecord.java Base (BASE)
> +++ src/com/sun/jini/mahalo/AbortRecord.java Locally Modified (Based On LOCAL)
> @@ -33,7 +33,7 @@
>     /**
>      * @serial
>      */
> -    private ParticipantHandle[] parts;
> +    private final ParticipantHandle[] parts;
> 
>     static final long serialVersionUID = -8121722031382234695L;
> 
> Index: src/com/sun/jini/mahalo/CommitJob.java
> --- src/com/sun/jini/mahalo/CommitJob.java Base (BASE)
> +++ src/com/sun/jini/mahalo/CommitJob.java Locally Modified (Based On LOCAL)
> @@ -29,6 +29,7 @@
> import java.rmi.ConnectIOException;
> import java.rmi.AccessException;
> import java.rmi.ConnectException;
> +import java.util.Iterator;
> 
> import java.util.logging.Level;
> import java.util.logging.Logger;
> @@ -51,10 +52,10 @@
>  * @see net.jini.core.transaction.server.TransactionParticipant
>  */
> public class CommitJob extends Job implements TransactionConstants {
> -    ServerTransaction tr;
> -    ClientLog log;
> -    ParticipantHandle[] handles;
> -    int maxtries = Integer.MAX_VALUE;
> +    final ServerTransaction tr;
> +    final ClientLog log;
> +    final ParticipantHandle[] handles;
> +    final int maxtries = Integer.MAX_VALUE;
>     static final Logger logger = TxnManagerImpl.participantLogger;
> 
>     /**
> @@ -266,13 +267,13 @@
> 	int tmp = 0;
> 	int count = 0;
> 
> -	checkresults:
> -	for (int i = 0; i < results.length; i++) {
> -	    tmp = ((Integer)results[i]).intValue();
> -
> -	    if (tmp == COMMITTED)
> -		count++;
> +        synchronized (this){
> +            Iterator i = results.values().iterator();
> +            while (i.hasNext()){
> +                tmp = ((Integer)i.next()).intValue();
> +                if (tmp == COMMITTED) count++;
> 	}
> +        }
> 
>         if (logger.isLoggable(Level.FINEST)) {
>             logger.log(Level.FINEST,
> Index: src/com/sun/jini/mahalo/CommitRecord.java
> --- src/com/sun/jini/mahalo/CommitRecord.java Base (BASE)
> +++ src/com/sun/jini/mahalo/CommitRecord.java Locally Modified (Based On LOCAL)
> @@ -39,7 +39,7 @@
>     /**
>      * @serial
>      */
> -    ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
> +    final ParticipantHandle[] parts; //Note: Use an array of ParticipantHandles;
> 			       //      We want a list of things.  By using
> 			       //      an array, we can use the type system
> 			       //      to guarantee that each thing is a
> Index: src/com/sun/jini/mahalo/Job.java
> --- src/com/sun/jini/mahalo/Job.java Base (BASE)
> +++ src/com/sun/jini/mahalo/Job.java Locally Modified (Based On LOCAL)
> @@ -19,9 +19,13 @@
> 
> import com.sun.jini.thread.TaskManager;
> import com.sun.jini.thread.WakeupManager;
> +import java.util.ArrayList;
> import java.util.HashMap;
> +import java.util.List;
> import java.util.Map;
> import java.util.Set;
> +import java.util.concurrent.ConcurrentHashMap;
> +import java.util.concurrent.atomic.AtomicIntegerArray;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> 
> @@ -34,14 +38,15 @@
>  *
>  */
> public abstract class Job {
> -    private TaskManager pool;
> -    private WakeupManager wm;
> -    private int pending = -1;
> -    Object[] results;
> -    int[] attempts;
> -    private Map tasks = new HashMap();  //used to maintain account
> +    private final TaskManager pool;
> +    private final WakeupManager wm;
> +    private int pending = -1; // Synchronized on this.
> +    final Map<Integer,Object> results = new HashMap<Integer,Object>(); // sync on this.
> +    volatile AtomicIntegerArray attempts; // reference changed while synchronized on this
> +    private final Map<Object,Integer> tasks = new HashMap<Object,Integer>();  //used to maintain account
> 					//of the tasks for which
> 					//the job is responsible
> +                                        // sync on tasks.
> 
>     static final Logger logger = TxnManagerImpl.participantLogger;
> 
> @@ -75,23 +80,31 @@
> 	}
> 
> 	if (tmp == null)
> -	    throw new UnknownTaskException();
> +	    throw new UnknownTaskException("Task didn't belong to this job");
> 
> 	int rank = tmp.intValue();
> 
> -	synchronized (attempts) {
> -	    attempts[rank]++;
> -	}
> +//	synchronized (attempts) {
> +//	    attempts[rank]++;
> +//	}
> 
> -	Object result = doWork(who, param);
> -	if (result == null)
> +        attempts.incrementAndGet(rank);
> +
> +	Object r = doWork(who, param);
> +	if (r == null)
> 	    return false;
> 
> 	try {
> -	    reportDone(who, result);
> +	    reportDone(who, r);
> 	} catch (UnknownTaskException e) {
> +            logger.log(Level.FINER, "trouble reporting job completion", e);
> +            e.printStackTrace(System.err);
> 	} catch (PartialResultException e) {
> +            logger.log(Level.FINER, "trouble reporting job completion", e);
> +            e.printStackTrace(System.err);
> 	} catch (JobException e) {
> +            logger.log(Level.FINER, "trouble reporting job completion", e);
> +            e.printStackTrace(System.err);
> 	}
> 
> 	return true;
> @@ -112,15 +125,14 @@
> 	    tmp = (Integer)tasks.get(who);
> 	}
> 
> -	if (tmp == null)
> -	    throw new UnknownTaskException();
> +	if (tmp == null) throw new UnknownTaskException();
> 
> 	int rank = tmp.intValue();
> -
> -	synchronized(attempts)  {
> -	    return attempts[rank];
> +//	synchronized(attempts)  {
> +//	    return attempts[rank];
> +//	}
> +        return attempts.get(rank);
> 	}
> -    }
> 
> 
> 
> @@ -150,37 +162,39 @@
>      */
>     public void scheduleTasks() {
> 	TaskManager.Task[] tmp = createTasks();
> -
> +        int length = tmp.length;
> 	if (tmp != null) {
>             if (logger.isLoggable(Level.FINEST)) {
>                 logger.log(Level.FINEST,
>                     "Job:scheduleTasks with {0} tasks",
> -                    Integer.valueOf(tmp.length));
> +                    Integer.valueOf(length));
>             }
> 
> -	    results = new Object[tmp.length];
> -	    attempts = new int[tmp.length];
> -	    setPending(tmp.length);
> +            synchronized (this){ 
> +                results.clear();
> +                attempts = new AtomicIntegerArray(length);
> +                setPending(length);
> +            }
> +            for (int i = 0; i < length; i++) {
> 
> -	    for (int i = 0; i < tmp.length; i++) {
> -
> 		//Record the position if each
> 		//task for later use when assembling
> 		//the partial results
> 
> 		synchronized(tasks) {
> 		    tasks.put(tmp[i],Integer.valueOf(i));
> +                }
> 		    pool.add(tmp[i]);
>                     if (logger.isLoggable(Level.FINEST)) {
>                         logger.log(Level.FINEST,
>                             "Job:scheduleTasks added {0} to thread pool",
>                             tmp[i]);
>                     }
> -		    attempts[i] = 0;
> +                attempts.set(i,0);
> 		}
> +            
> 	    }
> 	}
> -    }
> 
> 
>     private synchronized void awaitPending(long waitFor) {
> @@ -289,19 +303,21 @@
> 	if (position == null) 
> 	    throw new UnknownTaskException();
> 
> -	synchronized(results) {
> -	    if (results[position.intValue()] == null) {
> +        synchronized (this){
> +            Object exists = results.get(position);
> +            if (exists == null){
>                 if (logger.isLoggable(Level.FINEST)) {
>                     logger.log(Level.FINEST,
>                         "Job:reportDone who = {0}, param = {1}",
> 		        new Object[] { who, param});
>                 }
> -	        results[position.intValue()] = param;
> +                results.put(position, param);
> 	        decrementPending();
> 	    } else {
> 	        throw new PartialResultException("result already set");
> 	    }
> 	}
> +        
>     }
> 
> 
> @@ -347,21 +363,25 @@
>      * the <code>Job</code>
>      */
>     public void stop() {
> +        Object[] vals;
> +        synchronized (tasks){
> 	Set s = tasks.keySet();
> -	Object[] vals = s.toArray();
> +            vals = s.toArray();
> +            tasks.clear();
> +        }
> 
> 	//Remove and interrupt all tasks
> -
> -	for (int i = 0; i < vals.length; i++) {
> +        int l = vals.length;
> +	for (int i = 0; i < l; i++) {
> 	    TaskManager.Task t = (TaskManager.Task) vals[i];
> 	    pool.remove(t);
> 	}
> 
> 	//Erase record of tasks, results and the
> 	//counting mechanism
> -
> -	tasks = new HashMap();
> +        synchronized (this){
> 	setPending(-1);
> -	results = null;
> +            results.clear();
>     }
> }
> +}
> Index: src/com/sun/jini/mahalo/JoinStateManager.java
> --- src/com/sun/jini/mahalo/JoinStateManager.java Base (BASE)
> +++ src/com/sun/jini/mahalo/JoinStateManager.java Locally Modified (Based On LOCAL)
> @@ -74,41 +74,41 @@
>     private static final Logger persistenceLogger = TxnManagerImpl.persistenceLogger;
> 
>     /** <code>ProxyPreparer</code> for <code>LookupLocators</code> */
> -    private ProxyPreparer lookupLocatorPreparer;
> +    private volatile ProxyPreparer lookupLocatorPreparer;
> 
>     /**
>      * Object used to find lookups. Has to implement DiscoveryManagement
>      * and DiscoveryLocatorManagement as well as DiscoveryGroupManagement.
>      */
> -    private DiscoveryManagement dm;
> +    private volatile DiscoveryManagement dm;
> 
>     /**
>      * <code>JoinManager</code> that is handling the details of binding
>      * into Jini lookup services.
>      */
> -    private JoinManager  mgr;
> +    private volatile JoinManager  mgr;
> 
>     /**
>      * The object coordinating our persistent state.
>      */
> -    private ReliableLog log;
> +    private volatile ReliableLog log;
> 
>     /**
>      * The join state, this data needs to be persisted between restarts
>      */
> -    private Entry[]		attributes;
> -    private LookupLocator[]	locators;
> -    private String[]		groups;
> +    private volatile Entry[]		attributes;
> +    private volatile LookupLocator[]	locators;
> +    private volatile String[]		groups;
> 
>     /** Service's internal <code>Uuid</code> which needs to be persisted */
> -    private Uuid		serviceUuid;
> +    private volatile Uuid		serviceUuid;
> 
>     /**
>      * Conceptually, true if this is the first time this
>      * service has come up, implemented as if there was
>      * no previous state then this is the first time.
>      */
> -    private boolean initial = true;
> +    private volatile boolean initial = true;
> 
>     /**
>      * Simple constructor.
> Index: src/com/sun/jini/mahalo/LeaseExpirationMgr.java
> --- src/com/sun/jini/mahalo/LeaseExpirationMgr.java Base (BASE)
> +++ src/com/sun/jini/mahalo/LeaseExpirationMgr.java Locally Modified (Based On LOCAL)
> @@ -57,9 +57,9 @@
> 
> 
>     // Map of resources to tickets
> -    private WeakTable		ticketMap = new WeakTable(this); 
> -    private Expirer		landlord;
> -    private WakeupManager expirationQueue
> +    private final WeakTable		ticketMap = new WeakTable(this); 
> +    private final Expirer		landlord;
> +    private final WakeupManager expirationQueue
>         = new WakeupManager(new WakeupManager.ThreadDesc(null, true));
> 
>     /**
> Index: src/com/sun/jini/mahalo/ParticipantHandle.java
> --- src/com/sun/jini/mahalo/ParticipantHandle.java Base (BASE)
> +++ src/com/sun/jini/mahalo/ParticipantHandle.java Locally Modified (Based On LOCAL)
> @@ -38,17 +38,17 @@
>     /**
>      * Cached reference to prepared participant.
>      */
> -    private transient TransactionParticipant preparedPart;
> +    private volatile transient TransactionParticipant preparedPart;
> 
>     /**
>      * @serial
>      */
> -    private StorableObject storedpart;
> +    private final StorableObject storedpart;
> 
>     /**
>      * @serial
>      */
> -    private long crashcount = 0;
> +    private volatile long crashcount = 0;
> 
>     /**
>      * @serial
> @@ -70,6 +70,7 @@
>         if (preparedPart == null) 
> 	    throw new NullPointerException(
> 	        "TransactionParticipant argument cannot be null");
> +        StorableObject storedpart = null;
> 	try {
> 	    storedpart = new StorableObject(preparedPart);
> 	    this.preparedPart = preparedPart;
> @@ -80,6 +81,7 @@
> 		    "Cannot store the TransactionParticipant", re);
> 	    }
> 	}
> +        this.storedpart = storedpart;
> 	this.prepstate = ACTIVE;
>     }
> 
> Index: src/com/sun/jini/mahalo/ParticipantModRecord.java
> --- src/com/sun/jini/mahalo/ParticipantModRecord.java Base (BASE)
> +++ src/com/sun/jini/mahalo/ParticipantModRecord.java Locally Modified (Based On LOCAL)
> @@ -38,12 +38,12 @@
>     /**
>      * @serial
>      */
> -    private ParticipantHandle part;
> +    private final ParticipantHandle part;
> 
>     /**
>      * @serial
>      */
> -    private int result;
> +    private final int result;
> 
>     ParticipantModRecord(ParticipantHandle part, int result) {
> 	if (part == null)
> Index: src/com/sun/jini/mahalo/ParticipantTask.java
> --- src/com/sun/jini/mahalo/ParticipantTask.java Base (BASE)
> +++ src/com/sun/jini/mahalo/ParticipantTask.java Locally Modified (Based On LOCAL)
> @@ -17,6 +17,7 @@
>  */
> package com.sun.jini.mahalo;
> 
> +import com.sun.jini.logging.Levels;
> import com.sun.jini.thread.RetryTask;
> import com.sun.jini.thread.TaskManager;
> import com.sun.jini.thread.WakeupManager;
> @@ -35,8 +36,8 @@
>  * @see TaskManager
>  */
> public class ParticipantTask extends RetryTask {
> -    ParticipantHandle handle;
> -    Job myjob;
> +    final ParticipantHandle handle;
> +    final Job myjob;
>     private static final Logger operationsLogger = 
>         TxnManagerImpl.operationsLogger;
> 	
> @@ -81,9 +82,11 @@
> 	} catch (UnknownTaskException ute) {
> 	    //If task doesn't belong to the
> 	    //Job, then stop doing work.
> +            logger.log(Level.FINE, "Task didn't belong to job",ute);
> +            ute.printStackTrace(System.err);
> 	    result = true;
> 	} catch (JobException je) {
> -	    je.printStackTrace();
> +	    je.printStackTrace(System.err);
> 	}
>         if (operationsLogger.isLoggable(Level.FINER)) {
>             operationsLogger.exiting(ParticipantTask.class.getName(), 
> Index: src/com/sun/jini/mahalo/PrepareAndCommitJob.java
> --- src/com/sun/jini/mahalo/PrepareAndCommitJob.java Base (BASE)
> +++ src/com/sun/jini/mahalo/PrepareAndCommitJob.java Locally Modified (Based On LOCAL)
> @@ -45,10 +45,10 @@
>  * @see net.jini.core.transaction.server.TransactionParticipant
>  */
> public class PrepareAndCommitJob extends Job implements TransactionConstants {
> -    ServerTransaction tr;
> -    ClientLog log;
> -    ParticipantHandle handle;
> -    int maxtries = 5;
> +    final ServerTransaction tr;
> +    final ClientLog log;
> +    final ParticipantHandle handle;
> +    final int maxtries = 5;
> 
>     /*
>      * Field that holds the last received remote exception, if any.
> @@ -290,7 +290,9 @@
> 
> 	int prepstate = NOTCHANGED;
> 
> -	prepstate = ((Integer)results[0]).intValue();
> +        synchronized (this){
> +            prepstate = ((Integer) results.get(Integer.valueOf(0))).intValue();
> +        }
> 
>         Integer result = Integer.valueOf(prepstate);
>         if (operationsLogger.isLoggable(Level.FINER)) {
> Index: src/com/sun/jini/mahalo/PrepareJob.java
> --- src/com/sun/jini/mahalo/PrepareJob.java Base (BASE)
> +++ src/com/sun/jini/mahalo/PrepareJob.java Locally Modified (Based On LOCAL)
> @@ -22,6 +22,7 @@
> import com.sun.jini.thread.TaskManager;
> import com.sun.jini.thread.WakeupManager;
> import java.rmi.RemoteException;
> +import java.util.Iterator;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> import net.jini.core.transaction.Transaction;
> @@ -273,10 +274,11 @@
> 	int prepstate = NOTCHANGED;
> 	int tmp = 0;
> 
> -	checkresults:
> -	for (int i = 0; i < results.length; i++) {
> -	    tmp = ((Integer)results[i]).intValue();
> -
> +        synchronized (this){
> +            Iterator i = results.values().iterator();
> +            checkresult:
> +            while (i.hasNext()){
> +                tmp = ((Integer) i.next()).intValue();
> 	    switch(tmp) {
> 	      case NOTCHANGED:
> 		//Does not affect the prepstate
> @@ -288,7 +290,7 @@
> 		//aborts the whole transaction.
> 
> 		prepstate = ABORTED;
> -		break checkresults;
> +                    break checkresult;
> 
> 	      case PREPARED:
> 		//changes the state to PREPARED only
> @@ -298,11 +300,13 @@
> 		break;
> 	    }
> 	}
> -	Integer result = Integer.valueOf(prepstate);
> +        }
> +        
> +	Integer r = Integer.valueOf(prepstate);
>         if (operationsLogger.isLoggable(Level.FINER)) {
>             operationsLogger.exiting(PrepareJob.class.getName(),
> -                "computeResult", result);
> +                "computeResult", r);
> 	}
> -	return result;
> +	return r;
>     }
> }
> Index: src/com/sun/jini/mahalo/SettlerTask.java
> --- src/com/sun/jini/mahalo/SettlerTask.java Base (BASE)
> +++ src/com/sun/jini/mahalo/SettlerTask.java Locally Modified (Based On LOCAL)
> @@ -39,10 +39,10 @@
>  */
> 
> public class SettlerTask extends RetryTask implements TransactionConstants {
> -    private long tid;
> -    private int attempt;
> -    private int maxtries = Integer.MAX_VALUE;
> -    private TransactionManager txnmgr;
> +    private final long tid;
> +    private int attempt; // sync on this.
> +    private final int maxtries = Integer.MAX_VALUE;
> +    private final TransactionManager txnmgr;
> 
>     /** Logger for operations related messages */
>     private static final Logger operationsLogger = 
> @@ -89,10 +89,12 @@
> 	        "tryOnce");
> 	}
>         try {
> +            synchronized (this){
> 	    if (attempt >= maxtries)
> 		return true;
> 
> 	    attempt++;
> +            }
> 
> 	    if (transactionsLogger.isLoggable(Level.FINEST)) {
>                 transactionsLogger.log(Level.FINEST,
> Index: src/com/sun/jini/mahalo/StorableObject.java
> --- src/com/sun/jini/mahalo/StorableObject.java Base (BASE)
> +++ src/com/sun/jini/mahalo/StorableObject.java Locally Modified (Based On LOCAL)
> @@ -19,6 +19,7 @@
> package com.sun.jini.mahalo;
> 
> import java.io.IOException;
> +import java.io.ObjectInputStream;
> import java.rmi.MarshalledObject;
> import java.rmi.RemoteException;
> 
> @@ -39,8 +40,8 @@
>     /**
>      * @serial
>      */
> -    private MarshalledObject	bytes;	// the serialized bytes
> -    private transient Object	obj;	// the cached object reference
> +    private final MarshalledObject	bytes;	// the serialized bytes
> +    private volatile transient Object	obj;	// the cached object reference
> 
>     private static final boolean DEBUG = false;
>     private static final long serialVersionUID = -3793675220968988873L;
> @@ -50,16 +51,25 @@
>      * in a <code>MarshalledObject</code>.
>      */
>     public StorableObject(Object obj) throws RemoteException {
> +	this(obj, toMO(obj));
> +    }
> +    
> +    private static MarshalledObject toMO(Object obj) throws RemoteException{
> 	try {
> -	    bytes = new MarshalledObject(obj);
> -	    this.obj = obj;
> -	} catch (RemoteException e) {
> +            return new MarshalledObject(obj);
> +        } catch (RemoteException e){
> 	    throw e;
> -	} catch (IOException e) {
> +        } catch (IOException e){
> 	    fatalError("can't encode object", e);
> 	}
> +        return null; //Unreachable.
>     }
> 
> +    private StorableObject (Object obj, MarshalledObject mo){
> +        bytes = mo;
> +        this.obj = obj;
> +    }
> +    
>     /**
>      * Return the <code>hashCode</code> of the <code>MarshalledObject</code>.
>      */
> @@ -103,6 +113,12 @@
> 	return null;	// not reached, but compiler doesn't know
>     }
> 
> +    private void readObject(ObjectInputStream s)
> +                                   throws IOException, ClassNotFoundException
> +        {
> +            s.defaultReadObject(); // Just in case we change serial form later.
> +        }
> +
>     /**
>      * Unrecoverable error happened -- show it and give up the ghost.
>      */
> Index: src/com/sun/jini/mahalo/TxnManagerImpl.java
> --- src/com/sun/jini/mahalo/TxnManagerImpl.java Base (BASE)
> +++ src/com/sun/jini/mahalo/TxnManagerImpl.java Locally Modified (Based On LOCAL)
> @@ -62,6 +62,7 @@
> import java.util.Iterator;
> import java.util.Map;
> import java.util.Vector;
> +import java.util.concurrent.ConcurrentMap;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> 
> @@ -149,28 +150,6 @@
>     static final Logger persistenceLogger = 
>         Logger.getLogger(TxnManager.MAHALO + ".persistence");
> 
> -    /* At some point earlier in the development, it appears this object
> -     * was Serializable, or was declared so, such that it replaced itself
> -     * with a proxy stub.  This is a test to ensure serialization doesn't
> -     * occur.
> -     */
> -    
> -    private void writeObject(java.io.ObjectOutputStream out)
> -     throws IOException {
> -        throw new IOException("Serialization not supported");
> -    }
> -    private void readObject(java.io.ObjectInputStream in)
> -     throws IOException, ClassNotFoundException {
> -        throw new IOException("Serialization not supported");
> -    }
> -    private void readObjectNoData() 
> -     throws ObjectStreamException{
> -        throw new ObjectStreamException("Serialization not supported"){
> -            private static final long serialVersionUID = 1L;
> -        };
> -    }
> - 
> -    
>     private volatile LogManager logmgr;
>     /* Retrieve values from properties.          */
>     /* Its important here to schedule SettlerTasks on a */
> @@ -186,7 +165,7 @@
>     private final WakeupManager taskWakeupMgr;
>     /* Map of transaction ids are their associated, internal 
>      * transaction representations */
> -    private final Map<Long,TxnManagerTransaction> txns;
> +    private final ConcurrentMap<Long,TxnManagerTransaction> txns;
>     private final Vector<Long> unsettledtxns = new Vector<Long>();
>     private final InterruptedStatusThread settleThread;
>     private final String persistenceDirectory;
> @@ -390,7 +369,7 @@
>                 settleThread = init.settleThread;
>             } else {
>                 // Assign init fields
> -                txns = Collections.emptyMap();
> +                txns = null;
>                 /* Retrieve values from properties.          */
>                 activationSystem = null;
>                 activationID = activID;
> @@ -627,8 +606,7 @@
> 	        "prepared participant: {0}", preparedTarget);
> 	}
> 
> -        TxnManagerTransaction txntr =
> -		(TxnManagerTransaction) txns.get(Long.valueOf(id));
> +        TxnManagerTransaction txntr = txns.get(Long.valueOf(id));
> 
> 	if (txntr == null)
> 	    throw new UnknownTransactionException("unknown transaction");
> @@ -645,6 +623,7 @@
>     public int getState(long id)
>         throws UnknownTransactionException
>     {
> +        
>         if (operationsLogger.isLoggable(Level.FINER)) {
>             operationsLogger.entering(
> 		TxnManagerImpl.class.getName(), "getState", 
> @@ -652,9 +631,8 @@
> 	}
>         readyState.check();
> 
> -        TxnManagerTransaction txntr =
> -	        (TxnManagerTransaction) txns.get(Long.valueOf(id));
> -
> +        TxnManagerTransaction txntr = null;
> +                txntr = txns.get(Long.valueOf(id));
> 	if (txntr == null)
> 	    throw new UnknownTransactionException("unknown transaction");
>         /* Expiration checks are only meaningful for active transactions. */
> @@ -669,17 +647,18 @@
> 	 * a false result.
> 	 */
> //TODO - need better locking here. getState and expiration need to be checked atomically	
> -        int state = txntr.getState();
> -        if (state == ACTIVE && !ensureCurrent(txntr)) 
> -	    throw new UnknownTransactionException("unknown transaction");
> -	    
> +        try{
> +            int state = txntr.atomicCheckExpirationIfActive();
> 	if (operationsLogger.isLoggable(Level.FINER)) {
>             operationsLogger.exiting(
> 		TxnManagerImpl.class.getName(), "getState", 
> 	        Integer.valueOf(state));
> 	}
> 	return state;
> +        } catch (TransactionException ex) {
> +            throw new UnknownTransactionException("unknown transaction");
>     }
> +    }
> 
> 
>     public void commit(long id)
> @@ -901,12 +880,14 @@
>                     transactionsLogger.log(Level.FINEST,
>                         "Settler waiting");
> 	        }
> -		wait();
> -
> -	        if (transactionsLogger.isLoggable(Level.FINEST)) {
> -                    transactionsLogger.log(Level.FINEST,
> -                        "Settler notified");
> -	        }
> +                // Don't wait forever, in case we're not notified, break out
> +                // early and check condition.
> +		wait(10000L); 
> +                // Due to spurious wakeup and break out after ten seconds, the following log message is inaccurate.
> +//	        if (transactionsLogger.isLoggable(Level.FINEST)) {
> +//                    transactionsLogger.log(Level.FINEST,
> +//                        "Settler notified");
> +//	        }
> 		continue;
> 	    }
> 
> @@ -1018,6 +999,7 @@
> 
> 	// synchronize on the resource so there is not a race condition
> 	// between renew and expiration
> +        /* TODO check if synchronization correct */
> 	Result r;
> 	synchronized (txntr) {
> //TODO - check for ACTIVE too?
> @@ -1066,7 +1048,7 @@
> 
>         try {
>             // getState and expiration checked atomically
> -            txntr.checkStateActive(); // Throws UnknownLeaseException if state not ACTIVE.
> +            txntr.atomicCheckStateActive(); // throws TransactionException if state not ACTIVE.
>             // State is still active, make it expire.
>             txntr.setExpiration(0);	// Mark as done
>             abort(((Long)tid).longValue(), false);
> Index: src/com/sun/jini/mahalo/TxnManagerImplInitializer.java
> --- src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Base (BASE)
> +++ src/com/sun/jini/mahalo/TxnManagerImplInitializer.java Locally Modified (Based On LOCAL)
> @@ -38,6 +38,8 @@
> import java.util.HashMap;
> import java.util.Iterator;
> import java.util.Map;
> +import java.util.concurrent.ConcurrentHashMap;
> +import java.util.concurrent.ConcurrentMap;
> import java.util.logging.Level;
> import net.jini.activation.ActivationExporter;
> import net.jini.config.Configuration;
> @@ -64,7 +66,7 @@
>     int taskthreads = 50;
>     long tasktimeout = 1000 * 15;
>     float taskload = 1.0F;
> -    Map<Long, TxnManagerTransaction> txns = Collections.synchronizedMap(new HashMap<Long, TxnManagerTransaction>());
> +    ConcurrentMap<Long, TxnManagerTransaction> txns = new ConcurrentHashMap<Long, TxnManagerTransaction>();
>     /* Retrieve values from properties.          */
>     ActivationSystem activationSystem = null;
>     boolean activationPrepared = false;
> Index: src/com/sun/jini/mahalo/TxnManagerTransaction.java
> --- src/com/sun/jini/mahalo/TxnManagerTransaction.java Base (BASE)
> +++ src/com/sun/jini/mahalo/TxnManagerTransaction.java Locally Modified (Based On LOCAL)
> @@ -135,17 +135,17 @@
>     /**
>      * @serial
>      */
> -    private int trstate;
> +    private int trstate; //sync on stateLock
> 
>     /**
>      * @serial
>      */
> -    private long expires;		//expiration time
> +    private long expires;		//expiration time sync on leaseLock
> 
>     /**
>      * @serial
>      */
> -    private LogManager logmgr;
> +    private final LogManager logmgr;
> 
> 
>    /**
> @@ -180,27 +180,27 @@
>     *
>     * @serial
>     */
> -    private TaskManager threadpool;
> +    private final TaskManager threadpool;
> 
>     /**
>      * @serial
>      */
> -    private WakeupManager wm;
> +    private final WakeupManager wm;
> 
>     /**
>      * @serial
>      */
> -    private TxnSettler settler;
> +    private final TxnSettler settler;
> 
>     /**
>      * @serial
>      */
> -    private Job job;
> +    private Job job; // sync with jobLock
> 
>     /**
>      * @serial
>      */
> -    private Uuid uuid;
> +    private final Uuid uuid;
> 
>    /**
>     * Interlock for the expiration time since
> @@ -524,12 +524,21 @@
> 	}
>     }
> 
> +    public int atomicCheckExpirationIfActive() throws TransactionException {
> +        synchronized (stateLock){
> +            int state = getState();
> +            if (state == ACTIVE && !(getExpiration() > System.currentTimeMillis())) 
> +                throw new TransactionException("unknown transaction");
> +            return state;
> +        }
> +    }
> +
>     /**
>      * Atomic check that state is ACTIVE.
>      * @return ACTIVE if lease hasn't expired.
>      * @throws TransactionException otherwise.
>      */
> -    public int checkStateActive() throws TransactionException {
> +    public int atomicCheckStateActive() throws TransactionException {
>         synchronized (stateLock){
>             int state = getState();
>             if ((state == ACTIVE && getExpiration()==0) || (state != ACTIVE)) {
> @@ -839,13 +848,15 @@
> 								"ABORTED");
> 		  }
> 
> -                  if (getState() != COMMITTED)
> +                  if (getState() != COMMITTED){
> +                      synchronized (jobLock){
>                         throw new
>                             InternalManagerException("TxnManagerTransaction: " +
>                                     "commit: " + job + " got bad state: " +
>                                     TxnConstants.getName(result.intValue()));
> +                      }
> +                  }
> 
> -
> 		now = System.currentTimeMillis();
> 		transpired = now - starttime;
> 
> Index: src/com/sun/jini/mercury/MailboxImpl.java
> --- src/com/sun/jini/mercury/MailboxImpl.java Base (BASE)
> +++ src/com/sun/jini/mercury/MailboxImpl.java Locally Modified (Based On LOCAL)
> @@ -419,7 +419,7 @@
>     // constructor thread and set to null after starting.
>     private Configuration config;
>     private Throwable thrown;
> -    private volatile boolean started = false;
> +    private boolean started = false;
> 
>     ///////////////////////
>     // Activation Methods
> @@ -1071,8 +1071,8 @@
> //    } // End doInit()
> //    
>     public void start() throws Exception {
> -        if (started) return;
>         concurrentObj.writeLock();
> +        if (started) return;
>         started = true; // mutual exclusion
>         try {
>             if (thrown != null) throw thrown;
> Index: src/com/sun/jini/outrigger/EventRegistrationWatcher.java
> --- src/com/sun/jini/outrigger/EventRegistrationWatcher.java Base (BASE)
> +++ src/com/sun/jini/outrigger/EventRegistrationWatcher.java Locally Modified (Based On LOCAL)
> @@ -240,7 +240,7 @@
>      * @return The unique identifier associated with this
>      * watcher.
>      */
> -    public Uuid getCookie() {
> +    public synchronized Uuid getCookie() {
> 	return cookie;
>     }
> 
> Index: src/com/sun/jini/outrigger/OutriggerServerImpl.java
> --- src/com/sun/jini/outrigger/OutriggerServerImpl.java Base (BASE)
> +++ src/com/sun/jini/outrigger/OutriggerServerImpl.java Locally Modified (Based On LOCAL)
> @@ -647,6 +647,7 @@
>         if (except != null) throw except;
>         try {
>             // This takes a while the first time, so let's get it going
> +            txnMonitor.start();
>             starter.start();
> 
>             // Get store from configuration
> Index: src/com/sun/jini/outrigger/StorableEventWatcher.java
> --- src/com/sun/jini/outrigger/StorableEventWatcher.java Base (BASE)
> +++ src/com/sun/jini/outrigger/StorableEventWatcher.java Locally Modified (Based On LOCAL)
> @@ -36,7 +36,7 @@
>     implements StorableResource
> {
>     /** The listener that should be notified of matches */
> -    private StorableReference listener;
> +    private volatile StorableReference listener;
> 
>     /**
>      * Used during log recovery to create a mostly empty
> @@ -115,7 +115,7 @@
>      * @param expired <code>true</code> if being called from 
>      *        <code>removeIfExpired</code> and false otherwise. 
>      */
> -    void cleanup(TemplateHandle owner, boolean expired) {
> +    synchronized void cleanup(TemplateHandle owner, boolean expired) {
> 	if (expired)
> 	    owner.getServer().scheduleCancelOp(cookie);
> 	else 
> @@ -126,7 +126,7 @@
>     /**  
>      * Store the persistent fields 
>      */
> -    public void store(ObjectOutputStream out) throws IOException {
> +    public synchronized void store(ObjectOutputStream out) throws IOException {
> 	cookie.write(out);
> 	out.writeLong(expiration);
> 	out.writeLong(eventID);
> @@ -137,7 +137,7 @@
>     /**
>      * Restore the persistent fields
>      */
> -    public void restore(ObjectInputStream in) 
> +    public synchronized void restore(ObjectInputStream in) 
> 	throws IOException, ClassNotFoundException 
>     {
> 	cookie = UuidFactory.read(in);
> Index: src/com/sun/jini/outrigger/TxnMonitor.java
> --- src/com/sun/jini/outrigger/TxnMonitor.java Base (BASE)
> +++ src/com/sun/jini/outrigger/TxnMonitor.java Locally Modified (Based On LOCAL)
> @@ -51,8 +51,8 @@
>      * @see #pending
>      */
>     private static class ToMonitor {
> -	QueryWatcher	query;         // query governing interest in txns
> -	Collection	txns;	       // the transactions to monitor
> +	final QueryWatcher	query;         // query governing interest in txns
> +	final Collection	txns;	       // the transactions to monitor
> 
> 	ToMonitor(QueryWatcher query, Collection txns) {
> 	    this.query = query;
> @@ -71,7 +71,7 @@
>      * @see OutriggerServerImpl#getMatch 
>      */
>     // @see #ToMonitor
> -    private LinkedList pending = new LinkedList();
> +    private final LinkedList pending = new LinkedList();
> 
>     /** wakeup manager for <code>TxnMonitorTask</code>s */
>     private final WakeupManager wakeupMgr = 
> @@ -80,21 +80,23 @@
>     /**
>      * The manager for <code>TxnMonitorTask</code> objects.
>      */
> -    private TaskManager taskManager;
> +    private final TaskManager taskManager;
> 
>     /**
>      * The space we belong to.  Needed for aborts.
>      */
> -    private OutriggerServerImpl	space;
> +    private final OutriggerServerImpl	space;
> 
>     /**
>      * The thread running us.
>      */
> -    private Thread ourThread;
> +    private final Thread ourThread;
> 
>     /** Set when we are told to stop */
> -    private boolean die = false;
> +    private volatile boolean die = false;
> 
> +    private volatile boolean started = false;
> +
>     /** Logger for logging transaction related information */
>     private static final Logger logger = 
> 	Logger.getLogger(OutriggerServerImpl.txnLoggerName);
> @@ -115,8 +117,15 @@
> 
>         ourThread = new Thread(this, "TxnMonitor");
> 	ourThread.setDaemon(true);
> +//        ourThread.start();
> +    }
> +    
> +    public void start(){
> +        synchronized (this){
>         ourThread.start();
> +            started = true;
>     }
> +    }
> 
>     public void destroy() {
>         taskManager.terminate();
> @@ -128,7 +137,7 @@
> 	}
> 
>         try {
> -	    ourThread.join();
> +	    if (started) ourThread.join();
> 	} catch(InterruptedException ie) {
> 	    // ignore
> 	}
> Index: src/com/sun/jini/outrigger/TypeTree.java
> --- src/com/sun/jini/outrigger/TypeTree.java Base (BASE)
> +++ src/com/sun/jini/outrigger/TypeTree.java Locally Modified (Based On LOCAL)
> @@ -39,7 +39,7 @@
>  */
> class TypeTree {
>     /** For each type, a vector of known subtypes */
> -    private Hashtable subclasses = new Hashtable();
> +    private final Hashtable<String,Vector> subclasses = new Hashtable<String,Vector>();
> 
>     /**
>      * A generator used to randomize the order of iterator returns
> @@ -57,8 +57,10 @@
>      * Return the vector of subclasses for the given class.
>      */
>     private Vector classVector(String whichClass) {
> +        synchronized (subclasses){
> 	return (Vector) subclasses.get(whichClass);
>     }
> +    }
> 
>     /**
>      * An iterator that will walk through a list of known types.
> Index: src/com/sun/jini/thread/RetryTask.java
> --- src/com/sun/jini/thread/RetryTask.java Base (BASE)
> +++ src/com/sun/jini/thread/RetryTask.java Locally Modified (Based On LOCAL)
> @@ -64,7 +64,7 @@
> import com.sun.jini.thread.WakeupManager.Ticket;
> 
> public abstract class RetryTask implements TaskManager.Task, TimeConstants {
> -    private TaskManager	  manager;	// the TaskManager for this task
> +    private final TaskManager	  manager;	// the TaskManager for this task
>     private RetryTime	  retry;	// the retry object for this task
>     private boolean	  cancelled;	// have we been cancelled?
>     private boolean	  complete;	// have we completed successfully?
> @@ -72,7 +72,7 @@
>     private long	  startTime;	// the time when we were created or 
>                                         //   last reset
>     private int		  attempt;	// the current attempt number
> -    private WakeupManager wakeup;       // WakeupManager for retry scheduling
> +    private final WakeupManager wakeup;       // WakeupManager for retry scheduling
> 
>     /**
>      * Default delay backoff times.  These are converted from
> @@ -91,7 +91,7 @@
>     };
> 
>     /** Logger for this class */
> -    private static final Logger logger = 
> +    protected static final Logger logger = 
> 	Logger.getLogger("com.sun.jini.thread.RetryTask");
> 
>     /**
> @@ -128,7 +128,14 @@
> 		return;			// do nothing
> 	}
> 
> -	boolean success = tryOnce();
> +	boolean success = false;
> +        try {
> +            success = tryOnce();
> +        } catch (Throwable t){
> +            t.printStackTrace(System.err);
> +            if (t instanceof Error) throw (Error) t;
> +            if (t instanceof RuntimeException) throw (RuntimeException) t;
> +        }
> 
> 	synchronized (this) {
> 	    if (!success) {		// if at first we don't succeed ...
> Index: src/com/sun/jini/thread/TaskManager.java
> --- src/com/sun/jini/thread/TaskManager.java Base (BASE)
> +++ src/com/sun/jini/thread/TaskManager.java Locally Modified (Based On LOCAL)
> @@ -22,6 +22,7 @@
> import java.util.Collections;
> import java.util.Iterator;
> import java.util.List;
> +import java.util.concurrent.CopyOnWriteArrayList;
> import java.util.logging.Level;
> import java.util.logging.Logger;
> 
> @@ -77,13 +78,13 @@
> 	Logger.getLogger("com.sun.jini.thread.TaskManager");
> 
>     /** Active and pending tasks */
> -    protected final ArrayList tasks = new ArrayList();
> +    protected final ArrayList tasks = new ArrayList(); //sync on this
>     /** Index of the first pending task; all earlier tasks are active */
> -    protected int firstPending = 0;
> +    protected int firstPending = 0;//sync on this
>     /** Read-only view of tasks */
> -    protected final List roTasks = Collections.unmodifiableList(tasks);
> +    protected final List roTasks = Collections.unmodifiableList(tasks); // sync on this
>     /** Active threads */
> -    protected final List threads = new ArrayList();
> +    protected final List threads = new ArrayList(); //sync on this
>     /** Maximum number of threads allowed */
>     protected final int maxThreads;
>     /** Idle time before a thread should exit */
> @@ -91,7 +92,7 @@
>     /** Threshold for creating new threads */
>     protected final float loadFactor;
>     /** True if manager has been terminated */
> -    protected boolean terminated = false;
> +    protected boolean terminated = false; //sync on this
> 
>     /**
>      * Create a task manager with maxThreads = 10, timeout = 15 seconds,
> @@ -256,7 +257,7 @@
> 
>     /** Return all pending tasks.  A new list is returned each time. */
>     public synchronized ArrayList getPending() {
> -	ArrayList tc = (ArrayList)tasks.clone();
> +	ArrayList tc = new ArrayList(tasks);
> 	for (int i = firstPending; --i >= 0; ) {
> 	    tc.remove(0);
> 	}
> @@ -271,7 +272,7 @@
>     private class TaskThread extends Thread {
> 
> 	/** The task being run, if any */
> -	public Task task = null;
> +	public Task task = null; // sync access on TaskManager.this
> 
> 	public TaskThread() {
> 	    super("task");
> @@ -303,6 +304,7 @@
> 
> 	public void run() {
> 	    while (true) {
> +                Task tsk = null;
> 		synchronized (TaskManager.this) {
> 		    if (terminated)
> 			return;
> @@ -327,9 +329,10 @@
> 			    return;
> 			}
> 		    }
> +                    tsk = task;  
> 		}
> 		try {
> -		    task.run();
> +		    tsk.run();
> 		} catch (Throwable t) {
> 		    try {
> 			logger.log(Level.WARNING, "Task.run exception", t);
> Index: src/com/sun/jini/thread/WakeupManager.java
> --- src/com/sun/jini/thread/WakeupManager.java Base (BASE)
> +++ src/com/sun/jini/thread/WakeupManager.java Locally Modified (Based On LOCAL)
> @@ -493,7 +493,7 @@
>      * Assumes the caller holds the lock on contents.
>      */
>     private void checkHead() {
> -	assert Thread.holdsLock(contents);
> +        synchronized (contents){
> 	final Ticket oldHead = head;
> 
> 	if (contents.isEmpty())
> @@ -507,6 +507,7 @@
> 	// needs to wake up and change its sleep time.
> 	contents.notifyAll();
>     }
> +    }
> 
>     /**
>      * Return whether the queue is currently empty.
> Index: src/net/jini/lookup/JoinManager.java
> --- src/net/jini/lookup/JoinManager.java Base (BASE)
> +++ src/net/jini/lookup/JoinManager.java Locally Modified (Based On LOCAL)
> @@ -563,10 +563,11 @@
>     private class ProxyRegTask extends RetryTask {
>         private final long[] sleepTime = { 5*1000, 10*1000, 15*1000,
>                                           20*1000, 25*1000, 30*1000 };
> -        protected int tryIndx  = 0;
> -        protected int nRetries = 0;
> -        protected ProxyReg proxyReg;
> -        protected int seqN;
> +        // volatile fields only mutated while synchronized on proxyReg.taskList
> +        private volatile int tryIndx  = 0;
> +        private volatile int nRetries = 0;
> +        private final ProxyReg proxyReg;
> +        private volatile int seqN;
> 
>         /** Basic constructor; simply stores the input parameters */
>         ProxyRegTask(ProxyReg proxyReg, int seqN) {
> @@ -611,10 +612,11 @@
>                         if( !proxyReg.taskList.isEmpty() ) {
>                             proxyReg.taskList.remove(0);
>                         }//endif
> -                    }//end sync
>                     /* reset the retry info for the next task in the list */
>                     tryIndx  = 0;
>                     nRetries = 0;
> +                    }//end sync
> +                    
>                 } catch (Exception e) {
>                     return stopTrying(e);
>                 }
> @@ -627,8 +629,10 @@
>          */
>         public long retryTime() {
> 	    long nextTryTime = System.currentTimeMillis() + sleepTime[tryIndx];
> +            synchronized (proxyReg.taskList){
> 	    if(tryIndx < sleepTime.length-1)  tryIndx++;//don't go past end
>             nRetries++;
> +            }
>             return nextTryTime;
>         }//end retryTime
> 
> @@ -737,7 +741,7 @@
>     private abstract class JoinTask {
> 
>         /** Data structure referencing the task's associated lookup service */
> -        protected ProxyReg proxyReg;
> +        protected final ProxyReg proxyReg;
> 
>         /** Basic constructor; simply stores the input parameters */
>         JoinTask(ProxyReg proxyReg) {
> @@ -758,7 +762,7 @@
>          *  must not change during the registration process performed in
>          *  this this task.
>          */
> -        Entry[] regAttrs;
> +        final Entry[] regAttrs;
> 
>         /** Constructor that associates this task with the lookup service
>          *  referenced in the given <code>ProxyReg</code> parameter.
> @@ -889,9 +893,10 @@
>          */
>         public void run() {
>             logger.finest("JoinManager --> DiscardProxyTask started");
> -            if( (proxyReg != null) && (proxyReg.serviceLease != null) ) {
> +            Lease svcLease = proxyReg != null ? proxyReg.serviceLease : null;
> +            if( svcLease != null ) {
>                 try {
> -                    proxyReg.serviceLease.cancel();
> +                    svcLease.cancel();
>                 } catch (Exception e) { /*ignore*/ }
>             }//endif
>             logger.finest("JoinManager - DiscardProxyTask completed");
> @@ -1140,31 +1145,34 @@
>         /** The <code>ProxyRegTask</code> that instantiated this
>          *  <code>ProxyReg</code>.
>          */
> -        public ProxyRegTask proxyRegTask;
> +        volatile ProxyRegTask proxyRegTask;
>         /** The <i>prepared</i> proxy to the lookup service referenced by
>          *  this class, and with which this join manager's service will be
>          *  registered.
>          */
> -	public ServiceRegistrar proxy;
> +	final ServiceRegistrar proxy;
>         /** The <i>prepared</i> registration proxy returned by this class'
>          *  associated lookup service when this join manager registers its
>          *  associated service.
> +         * 
> +         * Access to reference synchronized on joinSet, but not referent
> +         * as it has foreign remote methods.
>          */
> -	public ServiceRegistration srvcRegistration = null;
> +	ServiceRegistration srvcRegistration = null;
>         /* The <i>prepared</i> proxy to the lease on the registration of this
>          * join manager's service with the this class' associated lookup
>          * service.
>          */
> -	public Lease serviceLease = null;
> +	volatile Lease serviceLease = null;
>         /** The set of sub-tasks that are to be executed in order for the
>          *  lookup service associated with the current instance of this class.
>          */
> -        public List taskList = new ArrayList(1);
> +        final List taskList = new ArrayList(1);
>         /** The instance of <code>DiscLeaseListener</code> that is registered
>          *  with the lease renewal manager that handles the lease of this join
>          *  manger's service.
>          */
> -	private DiscLeaseListener dListener = new DiscLeaseListener();
> +	private final DiscLeaseListener dListener = new DiscLeaseListener();
> 
>         /** Constructor that associates this class with the lookup service
>          *  referenced in the given <code>ProxyReg</code> parameter.
> @@ -1236,19 +1244,19 @@
>                 throw e; //rethrow the exception since proxy may be unusable
>             }
>             /* Retrieve and prepare the proxy to the service lease */
> -            serviceLease = tmpSrvcRegistration.getLease();
> +            Lease svcLease = tmpSrvcRegistration.getLease();
>             try {
> -                serviceLease = 
> -                       (Lease)serviceLeasePreparer.prepareProxy(serviceLease);
> +                this.serviceLease = 
> +                       (Lease)serviceLeasePreparer.prepareProxy(svcLease);
>                 logger.finest("JoinManager - service lease proxy prepared");
>             } catch(Exception e) {
> 		LogUtil.logThrow(logger, Level.WARNING, ProxyReg.class,
> 		    	"register", "JoinManager - failure during " +
> 		    	"preparation of service lease proxy: {0}",
> -		    	new Object[] { serviceLease }, e);
> +		    	new Object[] { svcLease }, e);
>                 throw e; //rethrow the exception since proxy may be unusable
>             }
> -            leaseRenewalMgr.renewUntil(serviceLease, Lease.FOREVER,
> +            leaseRenewalMgr.renewUntil(svcLease, Lease.FOREVER,
>                                        renewalDuration, dListener);
>             ServiceID tmpID = null;
>             synchronized(joinSet) {
> @@ -1272,7 +1280,11 @@
>          *  addition to that service's current set of attributes.
>          */
>         public void addAttributes(Entry[] attSet) throws Exception {
> -            srvcRegistration.addAttributes(attSet);
> +            ServiceRegistration sr;
> +            synchronized (joinSet){
> +                sr = srvcRegistration;
> +            }
> +            sr.addAttributes(attSet);
> 	}//end ProxyReg.addAttributes
> 
>         /** With respect to the lookup service referenced in this class
> @@ -1285,7 +1297,11 @@
>         public void modifyAttributes(Entry[] templ, Entry[] attSet)
>                                                              throws Exception
>         {
> -            srvcRegistration.modifyAttributes(templ, attSet);
> +            ServiceRegistration sr;
> +            synchronized (joinSet){
> +               sr = srvcRegistration;
> +            }
> +            sr.modifyAttributes(templ, attSet);
> 	}//end ProxyReg.modifyAttributes		    
> 
>         /** With respect to the lookup service referenced in this class
> @@ -1294,7 +1310,11 @@
>          *  set of attributes.
>          */
>         public void setAttributes(Entry[] attSet) throws Exception {
> -            srvcRegistration.setAttributes(attSet);
> +            ServiceRegistration sr;
> +            synchronized (joinSet){
> +               sr = srvcRegistration;
> +            }
> +            sr.setAttributes(attSet);
> 	}//end ProxyReg.setAttributes
> 
>         /** Convenience method that encapsulates appropriate behavior when
> @@ -1432,7 +1452,7 @@
>      *  which each task is associated). This field contains the value of
>      *  the sequence number assigned to the most recently created task.
>      */
> -    private int taskSeqN = 0;
> +    private int taskSeqN = 0; // access sync on taskList
>     /** Task manager for the various tasks executed by this join manager.
>      *  On the first attempt to execute any task is managed by this
>      *  <code>TaskManager</code> so that the number of concurrent threads
> @@ -1442,9 +1462,9 @@
>      *  "backoff strategy") - the re-execution of each failed task in this
>      *  <code>TaskManager</code>.
>      */
> -    private TaskManager taskMgr;
> +    private final TaskManager taskMgr;
>     /** Maximum number of times a failed task is allowed to be re-executed. */
> -    private int maxNRetries = 6;
> +    private final int maxNRetries;
>     /** Wakeup manager for the various tasks executed by this join manager.
>      *  After an initial failure of any task executed by this join manager,
>      *  the failed task is managed by this <code>WakeupManager</code>; which
> @@ -1456,22 +1476,22 @@
>      *  join manager is requested, all tasks scheduled for retry by this
>      *  wakeup manager can be cancelled.
>      */
> -    private WakeupManager wakeupMgr;
> +    private final WakeupManager wakeupMgr;
>     /** Contains the reference to the service that is to be registered with
>      *  all of the desired lookup services referenced by <code>discMgr</code>.
>      */
> -    private ServiceItem serviceItem;
> +    private final ServiceItem serviceItem;
>     /** Contains the attributes with which to associate the service in each
>      *  of the lookup services with which this join manager registers the
>      *  service.
>      */
> -    private Entry[] lookupAttr = null;
> +    private Entry[] lookupAttr = null; // access sync on joinSet
>     /** Contains the listener -- instantiated by the entity that constructs
>      *  this join manager -- that will receive an event containing the
>      *  service ID assigned to this join manager's service by one of the
>      *  lookup services with which that service is registered.
>      */
> -    private ServiceIDListener callback;
> +    private final ServiceIDListener callback;
>     /** Contains elements of type <code>ProxyReg</code> where each element
>      *  references a proxy to one of the lookup services with which this
>      *  join manager's service is registered.
> @@ -1480,22 +1500,22 @@
>     /** Contains the discovery manager that discovers the lookup services
>      *  with which this join manager will register its associated service.
>      */
> -    private DiscoveryManagement discMgr = null;
> +    private final DiscoveryManagement discMgr;
>     /** Contains the discovery listener registered by this join manager with
>      *  the discovery manager so that this join manager is notified whenever
>      *  one of the desired lookup services is discovered or discarded.
>      */
> -    private DiscMgrListener discMgrListener = new DiscMgrListener();
> +    private final DiscMgrListener discMgrListener ;
>     /** Flag that indicate whether the discovery manager employed by this
>      *  join manager was created by this join manager itself, or by the
>      *  entity that constructed this join manager.
>      */
> -    private boolean bCreateDiscMgr = false;
> +    private final boolean bCreateDiscMgr;
>     /** Contains the lease renewal manager that renews all of the leases
>      *  this join manager's service holds with each lookup service with which
>      *  it has been registered.
>      */
> -    private LeaseRenewalManager leaseRenewalMgr = null;
> +    private final LeaseRenewalManager leaseRenewalMgr;
>     /** The value to use as the <code>renewDuration</code> parameter
>      *  when invoking the lease renewal manager's <code>renewUntil</code>
>      *  method to add a service lease to manage. This value represents,
> @@ -1505,22 +1525,22 @@
>      *  is up, and lease expirations will occur sooner when the service
>      *  goes down.
>      */
> -    private long renewalDuration = Lease.FOREVER;
> +    private final long renewalDuration;
>     /** Flag that indicates if this join manager has been terminated. */
> -    private volatile boolean bTerminated = false;
> +    private boolean bTerminated = false; // All access sync on this.
>     /* Preparer for the proxies to the lookup services that are discovered
>      * and used by this utility.
>      */
> -    private ProxyPreparer registrarPreparer;
> +    private final ProxyPreparer registrarPreparer;
>     /* Preparer for the proxies to the registrations returned to this utility
>      * upon registering the service with each discovered lookup service.
>      */
> -    private ProxyPreparer registrationPreparer;
> +    private final ProxyPreparer registrationPreparer;
>     /* Preparer for the proxies to the leases returned to this utility through
>      * the registrations with each discovered lookup service with which this
>      * utility has registered the service.
>      */
> -    private ProxyPreparer serviceLeasePreparer;
> +    private final ProxyPreparer serviceLeasePreparer;
> 
>     /** 
>      * Constructs an instance of this class that will register the given
> @@ -1619,11 +1639,8 @@
> 			DiscoveryManagement discoveryMgr,
> 			LeaseRenewalManager leaseMgr)    throws IOException
>     {
> -        discMgr = discoveryMgr;
> -        try {
> -           createJoinManager(null, serviceProxy, attrSets, callback, leaseMgr,
> -                             EmptyConfiguration.INSTANCE);
> -        } catch(ConfigurationException e) { /* swallow this exception */ }
> +           this(serviceProxy, attrSets, null, callback, 
> +                 getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy));
>     }//end constructor
> 
>     /** 
> @@ -1737,9 +1754,10 @@
>                         Configuration config)
>                                     throws IOException, ConfigurationException
>     {
> -        discMgr = discoveryMgr;
> -        createJoinManager(null, serviceProxy, attrSets,
> -                          callback, leaseMgr, config);
> +        
> +        this(serviceProxy, attrSets, null, callback, 
> +            getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
> +        );
>     }//end constructor
> 
>     /** 
> @@ -1797,12 +1815,9 @@
> 			DiscoveryManagement discoveryMgr,
> 			LeaseRenewalManager leaseMgr)    throws IOException
>     {
> -        discMgr = discoveryMgr;
> -        try {
> -           createJoinManager(serviceID, serviceProxy, attrSets,
> -                             (ServiceIDListener)null, leaseMgr,
> -                             EmptyConfiguration.INSTANCE);
> -        } catch(ConfigurationException e) { /* swallow this exception */ }
> +       this(serviceProxy, attrSets, serviceID, null, 
> +             getConf(EmptyConfiguration.INSTANCE, leaseMgr, discoveryMgr, serviceProxy)
> +       );
>     }//end constructor
> 
>     /** 
> @@ -1877,9 +1892,9 @@
>                         Configuration config)
>                                     throws IOException, ConfigurationException
>     {
> -        discMgr = discoveryMgr;
> -        createJoinManager(serviceID, serviceProxy, attrSets,
> -                          (ServiceIDListener)null, leaseMgr, config);
> +        this(serviceProxy, attrSets, serviceID, null, 
> +             getConfig(config, leaseMgr, discoveryMgr, serviceProxy)
> +       );
>     }//end constructor
> 
>     /** 
> @@ -2464,44 +2479,113 @@
>         replaceRegistrationDo(serviceProxy, attrSets, true);
>     }//end replaceRegistration
> 
> -    /** Convenience method invoked by the constructors of this class that
> -     *  uses the given <code>Configuration</code> to initialize the current
> -     *  instance of this utility, and initiates all join processing for
> -     *  the given parameters. This method handles the various configurations
> -     *  allowed by the different constructors.
> +    private static class Conf{
> +        ProxyPreparer registrarPreparer;
> +        ProxyPreparer registrationPreparer;
> +        ProxyPreparer serviceLeasePreparer;
> +        TaskManager taskManager;
> +        WakeupManager wakeupManager;
> +        Integer maxNretrys;
> +        LeaseRenewalManager leaseRenewalManager;
> +        Long renewalDuration;
> +        DiscoveryManagement discoveryMgr;
> +        boolean bcreateDisco;
> +        
> +        Conf (  ProxyPreparer registrarPreparer,
> +                ProxyPreparer registrationPreparer,
> +                ProxyPreparer serviceLeasePreparer,
> +                TaskManager taskManager,
> +                WakeupManager wakeupManager,
> +                Integer maxNretrys,
> +                LeaseRenewalManager leaseRenewalManager,
> +                Long renewalDuration,
> +                DiscoveryManagement discoveryMgr,
> +                boolean bcreateDisco)
> +        {
> +            this.registrarPreparer = registrarPreparer;
> +            this.registrationPreparer = registrationPreparer;
> +            this.serviceLeasePreparer = serviceLeasePreparer;
> +            this.taskManager = taskManager;
> +            this.wakeupManager = wakeupManager;
> +            this.maxNretrys = maxNretrys;
> +            this.leaseRenewalManager = leaseRenewalManager;
> +            this.renewalDuration = renewalDuration;
> +            this.discoveryMgr = discoveryMgr;
> +            this.bcreateDisco = bcreateDisco;
> +        }
> +    }
> +    
> +    /**
> +     * This method is for constructors that use an empty configuration.
> +     * 
> +     * @param config
> +     * @param leaseMgr
> +     * @param discoveryMgr
> +     * @param serviceProxy
> +     * @return
> +     * @throws IOException
> +     * @throws NullPointerException
> +     * @throws IllegalArgumentException 
>      */
> -    private void createJoinManager(ServiceID serviceID, 
> -                                   Object serviceProxy,
> -                                   Entry[] attrSets, 
> -                                   ServiceIDListener callback,
> +    private static Conf getConf(    Configuration config,
>                                    LeaseRenewalManager leaseMgr,
> -                                   Configuration config) 
> -                                    throws IOException, ConfigurationException
> +                                    DiscoveryManagement discoveryMgr,
> +                                    Object serviceProxy) 
> +            throws IOException, NullPointerException, IllegalArgumentException {
> +        try {
> +            return getConfig(config, leaseMgr, discoveryMgr, serviceProxy);
> +        } catch (ConfigurationException e){
> +            throw new IOException("Configuration problem during construction", e);
> +        }
> +    }
> +    
> +    /**
> +     * Gets the configuration and throws any exceptions.
> +     * 
> +     * This static method guards against finalizer attacks and allows fields
> +     * to be final.
> +     * 
> +     * @param config
> +     * @param leaseMgr
> +     * @param discoveryMgr
> +     * @param serviceProxy
> +     * @return
> +     * @throws IOException
> +     * @throws ConfigurationException
> +     * @throws NullPointerException
> +     * @throws IllegalArgumentException 
> +     */
> +    private static Conf getConfig(  Configuration config,
> +                                    LeaseRenewalManager leaseMgr, 
> +                                    DiscoveryManagement discoveryMgr,
> +                                    Object serviceProxy) 
> +            throws IOException, ConfigurationException, NullPointerException,
> +            IllegalArgumentException 
>     {
> 	if(!(serviceProxy instanceof java.io.Serializable)) {
>             throw new IllegalArgumentException
>                                        ("serviceProxy must be Serializable");
> 	}//endif
> -
>         /* Retrieve configuration items if applicable */
>         if(config == null)  throw new NullPointerException("config is null");
>         /* Proxy preparers */
> -        registrarPreparer = (ProxyPreparer)config.getEntry
> +        ProxyPreparer registrarPreparer = (ProxyPreparer)config.getEntry
>                                                    (COMPONENT_NAME,
>                                                     "registrarPreparer",
>                                                     ProxyPreparer.class,
>                                                     new BasicProxyPreparer());
> -        registrationPreparer = (ProxyPreparer)config.getEntry
> +        ProxyPreparer registrationPreparer = (ProxyPreparer)config.getEntry
>                                                    (COMPONENT_NAME,
>                                                     "registrationPreparer",
>                                                     ProxyPreparer.class,
>                                                     new BasicProxyPreparer());
> -        serviceLeasePreparer = (ProxyPreparer)config.getEntry
> +        ProxyPreparer serviceLeasePreparer = (ProxyPreparer)config.getEntry
>                                                    (COMPONENT_NAME,
>                                                     "serviceLeasePreparer",
>                                                     ProxyPreparer.class,
>                                                     new BasicProxyPreparer());
>         /* Task manager */
> +        TaskManager taskMgr;
>         try {
>             taskMgr = (TaskManager)config.getEntry(COMPONENT_NAME,
>                                                    "taskManager",
> @@ -2510,6 +2594,7 @@
>             taskMgr = new TaskManager(MAX_N_TASKS,(15*1000),1.0f);
>         }
>         /* Wakeup manager */
> +        WakeupManager wakeupMgr;
>         try {
>             wakeupMgr = (WakeupManager)config.getEntry(COMPONENT_NAME,
>                                                        "wakeupManager",
> @@ -2519,57 +2604,84 @@
>                                     (new WakeupManager.ThreadDesc(null,true));
>         }
>         /* Max number of times to re-schedule tasks in thru wakeup manager */
> -        maxNRetries = ((Integer)config.getEntry
> +        Integer maxNRetries = ((Integer)config.getEntry
>                                         (COMPONENT_NAME,
>                                          "wakeupRetries",
>                                          int.class,
> -                                         Integer.valueOf(maxNRetries))).intValue();
> -        if(attrSets == null) {
> -            lookupAttr = new Entry[0];
> -        } else {
> -            attrSets = (Entry[])attrSets.clone();
> -            LookupAttributes.check(attrSets,false);//null elements NOT ok
> -            lookupAttr = attrSets;
> -        }//endif
> -	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
> +                                         Integer.valueOf(6))).intValue();
>         /* Lease renewal manager */
> -        leaseRenewalMgr = leaseMgr;
> -	if(leaseRenewalMgr == null) {
> +	if(leaseMgr == null) {
>             try {
> -                leaseRenewalMgr = (LeaseRenewalManager)config.getEntry
> +                leaseMgr = (LeaseRenewalManager)config.getEntry
>                                                   (COMPONENT_NAME,
>                                                    "leaseManager",
>                                                    LeaseRenewalManager.class);
>             } catch(NoSuchEntryException e) { /* use default */
> -                leaseRenewalMgr = new LeaseRenewalManager(config);
> +                leaseMgr = new LeaseRenewalManager(config);
>             }
>         }//endif
> -        renewalDuration = ((Long)config.getEntry
> +        Long renewalDuration = ((Long)config.getEntry
>                                       (COMPONENT_NAME,
>                                        "maxLeaseDuration",
>                                        long.class,
> -                                       Long.valueOf(renewalDuration))).longValue();
> +                                       Long.valueOf(Lease.FOREVER))).longValue();
>         if( (renewalDuration == 0) || (renewalDuration < Lease.ANY) ) {
>             throw new ConfigurationException("invalid configuration entry: "
>                                              +"renewalDuration ("
>                                              +renewalDuration+") must be "
>                                              +"positive or Lease.ANY");
>         }//endif
> -	this.callback = callback;
>         /* Discovery manager */
> -	if(discMgr == null) {
> +        boolean bCreateDiscMgr = false;
> +	if(discoveryMgr == null) {
> 	    bCreateDiscMgr = true;
>             try {
> -                discMgr = (DiscoveryManagement)config.getEntry
> +                discoveryMgr = (DiscoveryManagement)config.getEntry
>                                                  (COMPONENT_NAME,
>                                                   "discoveryManager",
>                                                   DiscoveryManagement.class);
>             } catch(NoSuchEntryException e) { /* use default */
> -                discMgr = new LookupDiscoveryManager
> +                discoveryMgr = new LookupDiscoveryManager
>                                      (new String[] {""}, null, null, config);
>             }
> 	}//endif
> -	discMgr.addDiscoveryListener(discMgrListener);
> +        return new Conf(registrarPreparer, registrationPreparer, serviceLeasePreparer,
> +                taskMgr, wakeupMgr, maxNRetries, leaseMgr, renewalDuration,
> +                discoveryMgr, bCreateDiscMgr);
> +    }
> +    
> +    /** Convenience method invoked by the constructors of this class that
> +     *  uses the given <code>Configuration</code> to initialize the current
> +     *  instance of this utility, and initiates all join processing for
> +     *  the given parameters. This method handles the various configurations
> +     *  allowed by the different constructors.
> +     */
> +    private JoinManager(Object serviceProxy,
> +                                   Entry[] attrSets, ServiceID serviceID, 
> +                                   ServiceIDListener callback, Conf conf)
> +    {
> +	registrarPreparer = conf.registrarPreparer;
> +        registrationPreparer = conf.registrationPreparer;
> +        serviceLeasePreparer = conf.serviceLeasePreparer;
> +        taskMgr = conf.taskManager;
> +        wakeupMgr = conf.wakeupManager;
> +        maxNRetries = conf.maxNretrys;
> +        leaseRenewalMgr = conf.leaseRenewalManager;
> +        renewalDuration = conf.renewalDuration;
> +        bCreateDiscMgr = conf.bcreateDisco;
> +        DiscMgrListener discMgrListen = new DiscMgrListener();
> +        if(attrSets == null) {
> +            lookupAttr = new Entry[0];
> +        } else {
> +            attrSets = attrSets.clone();
> +            LookupAttributes.check(attrSets,false);//null elements NOT ok
> +            lookupAttr = attrSets;
> +        }//endif
> +	serviceItem = new ServiceItem(serviceID, serviceProxy, lookupAttr);
> +	this.callback = callback;
> +	conf.discoveryMgr.addDiscoveryListener(discMgrListen);
> +        discMgr = conf.discoveryMgr;
> +        discMgrListener = discMgrListen;
>     }//end createJoinManager
> 
>     /** For the given lookup service proxy, searches the <code>joinSet</code>
> @@ -2623,9 +2735,10 @@
>                 }//end loop
>                 /* Interrupt all active tasks, prepare taskMgr for GC. */
>                 taskMgr.terminate();
> -                taskMgr = null;
> +        // Too lazy to put out the trash.
> +//                taskMgr = null;
>             }//end sync(taskMgr)
> -            wakeupMgr = null;
> +//            wakeupMgr = null;
>         }//end sync(wakeupMgr)
>     }//end terminateTaskMgr
> 
> Index: src/org/apache/river/api/security/URIGrant.java
> --- src/org/apache/river/api/security/URIGrant.java Base (BASE)
> +++ src/org/apache/river/api/security/URIGrant.java Locally Modified (Based On LOCAL)
> @@ -135,12 +135,17 @@
>         if (url == null ) return false;
>         Uri implied = null;
>         try {
> -            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
> -        } catch (PrivilegedActionException ex) {
> -            Exception cause = ex.getException();
> -            cause.printStackTrace(System.err);
> -            return false;
> +            implied = Uri.urlToUri(url);
> +        } catch (URISyntaxException ex) {
> +            Logger.getLogger(URIGrant.class.getName()).log(Level.SEVERE, null, ex);
>         }
> +//        try {
> +//            implied = AccessController.doPrivileged(new NormaliseURLAction(url));
> +//        } catch (PrivilegedActionException ex) {
> +//            Exception cause = ex.getException();
> +//            cause.printStackTrace(System.err);
> +//            return false;
> +//        }
>         for (int i = 0; i<l ; i++){
>             if (uris[i].implies(implied)) return true;
>         }