Search code examples
javaspringtomcatrabbitmqspring-rabbit

spring-rabbit is not stopping threads it starts when I shutdown Tomcat


When I shutdown tomcat, I get these messages in the log and the JVM does not release the process:

Jan 16, 2015 4:20:25 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/myproject] appears to have started a thread named [SimpleAsyncTaskExecutor-1] but has failed to stop it. This is very likely to create a memory leak.
Jan 16, 2015 4:20:25 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/myproject] appears to have started a thread named [pool-1-thread-1] but has failed to stop it. This is very likely to create a memory leak.
Jan 16, 2015 4:20:25 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/myproject] appears to have started a thread named [pool-1-thread-2] but has failed to stop it. This is very likely to create a memory leak.
Jan 16, 2015 4:20:25 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/myproject] appears to have started a thread named [pool-1-thread-3] but has failed to stop it. This is very likely to create a memory leak.
Jan 16, 2015 4:20:25 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/myproject] appears to have started a thread named [SimpleAsyncTaskExecutor-1] but has failed to stop it. This is very likely to create a memory leak.
Jan 16, 2015 4:20:25 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/myproject] appears to have started a thread named [pool-1-thread-4] but has failed to stop it. This is very likely to create a memory leak.

I used a debugger to see what those threads are doing before shutdown, and this is one of their thread dumps:

"SimpleAsyncTaskExecutor-1@4510" prio=5 tid=0x29 nid=NA waiting
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.nextMessage(BlockingQueueConsumer.java:302)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:945)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:934)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$600(SimpleMessageListenerContainer.java:78)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1045)
at java.lang.Thread.run(Thread.java:745)

I'm using this as evidence that spring/spring-rabbit is responsible for this issue.

This is the part of my Spring context that has to do with rabbit mq:

<rabbit:connection-factory id="connectionFactory" host="host" port="5672" username="username" password="password" virtual-host="/projectname"/>

<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" exchange="barExchange"/>

<rabbit:queue name="barQueueCleanDev" />
<rabbit:queue name="barQueueFooDev" />

<rabbit:topic-exchange name="barExchange" >
<rabbit:bindings>
<rabbit:binding queue="barQueueFooDev" pattern="bar.queue.foo.dev" />
<rabbit:binding queue="barQueueCleanDev" pattern="bar.queue.clean.dev" />
</rabbit:bindings>
</rabbit:topic-exchange>

<rabbit:listener-container connection-factory="connectionFactory" acknowledge="auto" concurrency="1" max-concurrency="1" requeue-rejected="false" error-handler="barServiceErrorHandler">
<rabbit:listener ref="barService" method="create" queue-names="barQueueCleanDev"/>
<rabbit:listener ref="barService" method="createFromFoo" queue-names="barQueueFooDev"/>
</rabbit:listener-container>

How do I tell spring-rabbit to stop the threads its created when I shutdown tomcat?

I'm using spring-rabbit version 1.4.2.RELEASE


Solution

  • I fixed this by manually calling my Spring's applicationContext.destroy() in a servlet's destroy method.