[
https://issues.apache.org/jira/browse/AMQ-4166?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Sergiy Barlabanov updated AMQ-4166:
-----------------------------------
Attachment: stack-trace-2.txt
stack-trace-1.txt
broker-config.xml
Broker config and the stack traces of the participating threads.
> RedeliveryPlugin causes a deadlock with JobSchedulerImpl
> --------------------------------------------------------
>
> Key: AMQ-4166
> URL: https://issues.apache.org/jira/browse/AMQ-4166
> Project: ActiveMQ
> Issue Type: Bug
> Components: Broker
> Affects Versions: 5.7.0
> Environment: Reproduced on Windows 8, Windows Vista, MacOS X
> with Oracle jdk 1.7.0_07. ActiveMQ is started embedded using RAR inside
> Glassfish 3.1.2.2.
> Reporter: Sergiy Barlabanov
> Attachments: broker-config.xml, stack-trace-1.txt, stack-trace-2.txt
>
>
> Originates from the forum discussion
> http://activemq.2283324.n4.nabble.com/RedeliveryPlugin-causes-a-deadlock-with-JobSchedulerImpl-in-ActiveMQ-5-7-0-tt4659019.html
> we have RedeliveryPlugin causing thread deadlock together with
> JobSchedulerImpl. ActiveMQ version is 5.7.0. We activated RedeliveryPlugin in
> our broker config xml (see below). There two stacktraces below as well. One
> is from ActiveMQ VMTransport thread, which tries to send a message to a dead
> letter queue using RedeliveryPlugin. RedeliveryPlugin just tries to
> reschedule the message for redelivery and for that it calls JobSchedulerImpl
> and blocks on its synchronized method "schedule". On the way "consumersLock"
> is locked.
> Another stack trace is from JobScheduler:JMS thread, which fires a job to
> redeliver some message and tries to send it using the same queue used by the
> VMTransport thread. And it blocks on that consumersLock locked by the
> VMTransport thread. And this occurs in JobSchedulerImpl#mainLoop method
> inside synchronized {} block causing a deadlock, since the VMTransport thread
> tries to call another synchronized method of JobSchedulerImpl. The art how
> RedeliveryPlugin and JobSchedulerImpl are programmed seems to be quite
> dangerous, since they both access the queues and try to acquire queue locks.
> And additionally synchronized methods of JobSchedulerImpl are called directly
> from RedeliveryPlugin making that to a nice source of thread deadlocks. And I
> see no measures taken in the code to avoid these deadlocks.
> We can reproduce it quite often if we start ActiveMQ with empty stores
> (kahadb and scheduler stores are deleted manually from the file system before
> startup). But looking at the code, I would say that the problem may occur in
> any situation in any deployment scenario (standalone or embedded in a JEE
> container). It is just enough to have some Transport thread redelivering a
> message and the JobScheduler thread trying to fire a job at the same moment
> on the same queue.
> And another strange thing, which is may be has nothing to do with the
> deadlock but is still strange, is that according to the stack trace
> RedeliveryPlugin tries to redeliver an expired message.
> Our broker configuration:
> <broker xmlns="http://activemq.apache.org/schema/core" brokerName="dcdng"
> useJmx="true" useShutdownHook="false" schedulerSupport="false">
> <managementContext>
>
> <managementContext createConnector="false"/>
> </managementContext>
> <persistenceAdapter>
> <kahaDB directory="${activemq.message.storage}"
> journalMaxFileLength="10mb"/>
> </persistenceAdapter>
> <transportConnectors>
> <transportConnector uri="${activemq.connector.address}"/>
> </transportConnectors>
> <destinationPolicy>
> <policyMap>
> <policyEntries>
>
> <policyEntry queue=">" producerFlowControl="true">
> <deadLetterStrategy>
>
> <individualDeadLetterStrategy queuePrefix="DLQ."
> useQueueForQueueMessages="true" processExpired="false" enableAudit="false"/>
> </deadLetterStrategy>
> </policyEntry>
> </policyEntries>
> </policyMap>
> </destinationPolicy>
> <plugins>
> <redeliveryPlugin fallbackToDeadLetter="true"
> sendToDlqIfMaxRetriesExceeded="true">
> <redeliveryPolicyMap>
> <redeliveryPolicyMap>
> <redeliveryPolicyEntries>
> <redeliveryPolicy queue="EventQueue"
> maximumRedeliveries="10"
> redeliveryDelay="1000"/>
> </redeliveryPolicyEntries>
> <defaultEntry>
> <redeliveryPolicy maximumRedeliveries="3"
> redeliveryDelay="1000"/>
> </defaultEntry>
> </redeliveryPolicyMap>
> </redeliveryPolicyMap>
> </redeliveryPlugin>
> </plugins>
> <systemUsage>
> <systemUsage sendFailIfNoSpace="true">
> <memoryUsage>
> <memoryUsage limit="200 mb"/>
> </memoryUsage>
> <storeUsage>
> <storeUsage limit="1000 mb"/>
> </storeUsage>
> <tempUsage>
> <tempUsage limit="200 mb"/>
> </tempUsage>
> </systemUsage>
> </systemUsage>
> </broker>
> Stack trace #1:
> Name: ActiveMQ VMTransport: vm://dcdng#101-1
> State: BLOCKED on
> org.apache.activemq.broker.scheduler.JobSchedulerImpl@6a135124 owned by:
> JobScheduler:JMS
> Total blocked: 22 Total waited: 13
> org.apache.activemq.broker.scheduler.JobSchedulerImpl.schedule(JobSchedulerImpl.java:110)
>
> org.apache.activemq.broker.scheduler.SchedulerBroker.send(SchedulerBroker.java:185)
>
> org.apache.activemq.broker.BrokerFilter.send(BrokerFilter.java:129)
> org.apache.activemq.broker.CompositeDestinationBroker.send(CompositeDestinationBroker.java:96)
>
> org.apache.activemq.broker.TransactionBroker.send(TransactionBroker.java:317)
> org.apache.activemq.broker.MutableBrokerFilter.send(MutableBrokerFilter.java:135)
>
> org.apache.activemq.broker.MutableBrokerFilter.send(MutableBrokerFilter.java:135)
>
> org.apache.activemq.broker.util.RedeliveryPlugin.scheduleRedelivery(RedeliveryPlugin.java:190)
>
> org.apache.activemq.broker.util.RedeliveryPlugin.sendToDeadLetterQueue(RedeliveryPlugin.java:144)
>
> org.apache.activemq.broker.MutableBrokerFilter.sendToDeadLetterQueue(MutableBrokerFilter.java:274)
>
> org.apache.activemq.broker.region.RegionBroker.messageExpired(RegionBroker.java:798)
>
> org.apache.activemq.broker.BrokerFilter.messageExpired(BrokerFilter.java:257)
> org.apache.activemq.broker.BrokerFilter.messageExpired(BrokerFilter.java:257)
> org.apache.activemq.advisory.AdvisoryBroker.messageExpired(AdvisoryBroker.java:284)
>
> org.apache.activemq.broker.BrokerFilter.messageExpired(BrokerFilter.java:257)
> org.apache.activemq.broker.BrokerFilter.messageExpired(BrokerFilter.java:257)
> org.apache.activemq.broker.MutableBrokerFilter.messageExpired(MutableBrokerFilter.java:269)
>
> org.apache.activemq.broker.MutableBrokerFilter.messageExpired(MutableBrokerFilter.java:269)
>
> org.apache.activemq.broker.region.Queue.messageExpired(Queue.java:1657)
> org.apache.activemq.broker.region.PrefetchSubscription.dispatchPending(PrefetchSubscription.java:640)
>
> - locked java.lang.Object@7b97909e
> - locked java.lang.Object@1b97b476
> org.apache.activemq.broker.region.PrefetchSubscription.add(PrefetchSubscription.java:155)
>
> org.apache.activemq.broker.region.Queue.doActualDispatch(Queue.java:1897)
> org.apache.activemq.broker.region.Queue.doDispatch(Queue.java:1824)
> org.apache.activemq.broker.region.Queue.removeSubscription(Queue.java:572)
> org.apache.activemq.broker.region.AbstractRegion.removeConsumer(AbstractRegion.java:381)
>
> org.apache.activemq.broker.region.RegionBroker.removeConsumer(RegionBroker.java:445)
>
> org.apache.activemq.broker.jmx.ManagedRegionBroker.removeConsumer(ManagedRegionBroker.java:275)
>
> org.apache.activemq.broker.BrokerFilter.removeConsumer(BrokerFilter.java:117)
> org.apache.activemq.broker.BrokerFilter.removeConsumer(BrokerFilter.java:117)
> org.apache.activemq.advisory.AdvisoryBroker.removeConsumer(AdvisoryBroker.java:254)
>
> org.apache.activemq.broker.BrokerFilter.removeConsumer(BrokerFilter.java:117)
> org.apache.activemq.broker.BrokerFilter.removeConsumer(BrokerFilter.java:117)
> org.apache.activemq.broker.MutableBrokerFilter.removeConsumer(MutableBrokerFilter.java:123)
>
> org.apache.activemq.broker.MutableBrokerFilter.removeConsumer(MutableBrokerFilter.java:123)
>
> org.apache.activemq.broker.TransportConnection.processRemoveConsumer(TransportConnection.java:593)
>
> org.apache.activemq.command.RemoveInfo.visit(RemoveInfo.java:76)
> org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:294)
>
> org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:152)
>
> org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:116)
>
> org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)
>
> org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:241)
> org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:129)
>
> org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:47)
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
>
> java.lang.Thread.run(Thread.java:722)
> Stack trace #2:
> Name: JobScheduler:JMS
> State: WAITING on
> java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync@30001430 owned
> by: ActiveMQ VMTransport: vm://dcdng#101-1
> Total blocked: 15 Total waited: 480
>
> Stack trace:
> sun.misc.Unsafe.park(Native Method)
> java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
> java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
>
> java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireShared(AbstractQueuedSynchronizer.java:964)
>
> java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared(AbstractQueuedSynchronizer.java:1282)
>
> java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock(ReentrantReadWriteLock.java:731)
>
> org.apache.activemq.broker.region.Queue.messageSent(Queue.java:1679)
> org.apache.activemq.broker.region.Queue.doMessageSend(Queue.java:791)
> org.apache.activemq.broker.region.Queue.send(Queue.java:717)
> org.apache.activemq.broker.region.AbstractRegion.send(AbstractRegion.java:407)
>
> org.apache.activemq.broker.region.RegionBroker.send(RegionBroker.java:503)
> org.apache.activemq.broker.jmx.ManagedRegionBroker.send(ManagedRegionBroker.java:311)
>
> org.apache.activemq.broker.BrokerFilter.send(BrokerFilter.java:129)
> org.apache.activemq.broker.scheduler.SchedulerBroker.scheduledJob(SchedulerBroker.java:251)
>
> org.apache.activemq.broker.scheduler.JobSchedulerImpl.fireJob(JobSchedulerImpl.java:423)
>
> org.apache.activemq.broker.scheduler.JobSchedulerImpl.mainLoop(JobSchedulerImpl.java:473)
>
> - locked org.apache.activemq.broker.scheduler.JobSchedulerImpl@6a135124
> org.apache.activemq.broker.scheduler.JobSchedulerImpl.run(JobSchedulerImpl.java:429)
>
> java.lang.Thread.run(Thread.java:722)
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira