You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by bonnyr <bo...@optusnet.com.au> on 2009/02/06 07:24:51 UTC

ConcurrentModificationException while closing consumer

AMQ 5.1 (but problem exists in the sources of AMQ-5.2 as of today)

My setup:
* Broker is configured with a single queue, full with messages, on a host
accessible via the network.
* Application configured with a single consumer, connected to a single
sesssion, running in its own thread.
* ActiveMQ delivers lots of messages using one of the ActiveMQSessionTask
threads.
* Session configured as CLIENT_ACKNOLEDGE


Since the queue is full of messages, delivery of these messages happen as
fast as the network
can deliver and the AMQ thread is invoking the onMessage with each new
message. These messages
are then processed by the consumer thread. The consumer thread then decides
to close the connection 
and the following ensues:
[code]
java.util.ConcurrentModificationException
        at
java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:617)
        at java.util.LinkedList$ListItr.next(LinkedList.java:552)
        at
org.apache.activemq.ActiveMQMessageConsumer.dispose(ActiveMQMessageConsumer.java:663)
        at
org.apache.activemq.ActiveMQMessageConsumer.close(ActiveMQMessageConsumer.java:583)
        at
com.xxx.app..AMsgQueueConsumer.doClose(AMsgQueueConsumer.java:351)
        at com.xxx.app.AMsgQueueConsumer.suspend

        ... snip ...

[/code]

This happens because AMQ is busy delivering messages and there is a
collection [b]deliveredMessages[/b] that is 
not protected by synchronisation in exactly one place (everywhere else it
is...) which is executing the
following code (in the dispose method):
[code]
 ... snip ...
            if (session.isClientAcknowledge()) {
                if (!this.info.isBrowser()) {
                    // rollback duplicates that aren't acknowledged
                    for (MessageDispatch old : deliveredMessages) {
                        session.connection.rollbackDuplicate(this,
old.getMessage());
                    }
                }
            }
 ... snip ...
[/code]

Since the code iterates over the collection, and the iterator checks for
modifications to the underlying collection, and since the AMQ message
delivery thread has managed to sneak in a couple more messages
while the consumer thread attempted to close the connection, the problem
occurs (it could be that
the for syntax hides the explicit iterator calls, but...)


Is this an ommission or is there a reason for not synchronising access to
this collection? If it's not a bug
then how should the consumer be disconnected?

Cheers,

Bonny
-- 
View this message in context: http://www.nabble.com/ConcurrentModificationException-while-closing-consumer-tp21867251p21867251.html
Sent from the ActiveMQ - User mailing list archive at Nabble.com.