[
https://issues.apache.org/activemq/browse/AMQ-2652?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Bruce Snyder updated AMQ-2652:
------------------------------
Fix Version/s: 5.5.0
(was: 5.4.1)
> ActiveMQ non-conformance to JMS Spec causing deadlock when using 3rd-party
> Resource Adapter
> -------------------------------------------------------------------------------------------
>
> Key: AMQ-2652
> URL: https://issues.apache.org/activemq/browse/AMQ-2652
> Project: ActiveMQ
> Issue Type: Bug
> Affects Versions: 5.3.0
> Reporter: Eugene Rodos
> Fix For: 5.5.0
>
> Attachments: BlockingServerSessionPoolDeadlockTest.java
>
>
> Linked to forum discussion:
> http://old.nabble.com/ActiveMQ-non-conformance-to-JMS-Spec-causing-deadlock-when-using-3rd-party-Resource-Adapter-tt27869447.html
> The following is an excerpt from the JMS Spec 1.1:
> {quote}
> *8.2.3 ServerSessionPool*
> ...<snip>...
> If the ServerSessionPool is out of ServerSessions, the
> getServerSession() method
> may block. If a ConnectionConsumer is blocked, it cannot deliver new
> messages
> until a ServerSession is eventually returned.
> {quote}
> \\
> I am using a 3rd-party JMS Resource Adapter to integrate ActiveMQ with a J2EE
> app server. This Resource Adapter does just what the JMS Spec above allows -
> it blocks in the ServerSessionPool.getServerSession() call when it is out of
> ServerSessions. This causes ActiveMQ to hang due to a deadlock.
> The deadlock occurs because the ServerSessionPool uses a single connection to
> service all its ServerSessions. This is perfectly legal. However, ActiveMQ
> is using this same connection for both dispatching messages to the
> ConnectionConsumer as well as communicating transaction commits to the JMS
> engine.
> So the deadlock scenario is as follows:
> \- message 1 is dispatched to the ConnectionConsumer and is being processed
> \- before message 1 is committed, message 2 is dispatched
> \- ServerSession is requested for processing message 2
> \- ServerSessionPool.getServerSession() blocks because it is out of
> ServerSessions, blocking the connection from which the call was made
> \- message 1 is finished processing and the tx is committed
> \- ActiveMQ does a synchronous send using the same connection that is
> currently blocked, to communicate the transaction commit command
> \- the commit blocks waiting for the connection to be released which will
> never happen because that release is dependent on the ServerSession being
> returned to the pool which won't happen until the tx is committed
> The stacktraces of the 2 deadlocked threads at the time of the deadlock are
> as follows:
> {noformat}
> "ActiveMQ Transport: tcp://localhost/127.0.0.1:61616" prio=6 tid=0x0aecc9f8
> nid=0x1414 in Object.wait() [0x0b6af000..0x0b6afc68]
> at java.lang.Object.wait(Native Method)
> - waiting on <0x03070188> (a
> org.apache.activemq.BlockingServerSessionPoolDeadlockTest$TestServerSessionPool)
> at java.lang.Object.wait(Object.java:474)
> at
> org.apache.activemq.BlockingServerSessionPoolDeadlockTest$TestServerSessionPool.getServerSession(BlockingServerSessionPoolDeadlockTest.java:106)
> - locked <0x03070188> (a
> org.apache.activemq.BlockingServerSessionPoolDeadlockTest$TestServerSessionPool)
> at
> org.apache.activemq.ActiveMQConnectionConsumer.dispatch(ActiveMQConnectionConsumer.java:129)
> at
> org.apache.activemq.ActiveMQConnection$2.processMessageDispatch(ActiveMQConnection.java:1676)
> at
> org.apache.activemq.command.MessageDispatch.visit(MessageDispatch.java:108)
> at
> org.apache.activemq.ActiveMQConnection.onCommand(ActiveMQConnection.java:1658)
> at
> org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:109)
> at
> org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
> at
> org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:113)
> at
> org.apache.activemq.transport.InactivityMonitor.onCommand(InactivityMonitor.java:210)
> - locked <0x03064e98> (a
> org.apache.activemq.transport.InactivityMonitor$1)
> at
> org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:84)
> at
> org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:203)
> at
> org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:185)
> at java.lang.Thread.run(Thread.java:595)
>
> "Thread-5" prio=6 tid=0x0af48ae0 nid=0x14a4 waiting on condition
> [0x0b8af000..0x0b8afbe8]
> at sun.misc.Unsafe.park(Native Method)
> at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
> at
> java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1841)
> at
> java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:341)
> at
> org.apache.activemq.transport.FutureResponse.getResult(FutureResponse.java:40)
> at
> org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:80)
> at
> org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1244)
> at
> org.apache.activemq.TransactionContext.syncSendPacketWithInterruptionHandling(TransactionContext.java:643)
> at
> org.apache.activemq.TransactionContext.commit(TransactionContext.java:286)
> at org.apache.activemq.ActiveMQSession.commit(ActiveMQSession.java:510)
> at
> org.apache.activemq.BlockingServerSessionPoolDeadlockTest$TestServerSession$1.run(BlockingServerSessionPoolDeadlockTest.java:140)
> {noformat}
> \\
> I'm attaching a junit test that illustrates this deadlock.
> Now, I realize that this bug does not manifest itself if the ActiveMQ
> Resource Adapter is used. However, that is only because of the way AMQ RA
> works - it reuses existing ServerSessions instead of blocking when it runs
> out (and does a weird callback from the jms session to the ServerSession to
> start a tx, in order to avoid delivering several messages on same tx which is
> what would happen when reusing an existing ServerSession that is already in
> the middle of processing another message).
> I think this is a bug in AMQ JMS engine's implementation which just happens
> to be masked by the way AMQ RA is implemented. If a Resource Adapted relies
> on the blocking behavior clearly provisioned by the JMS Spec, the problem
> becomes evident.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.