[ https://issues.apache.org/jira/browse/CAMEL-22026?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Kartik updated CAMEL-22026: --------------------------- Description: The camel sjms and sjms2 component cause thread to leak and the connection is kept open despite the route is stopped. I am using ActiveMQ broker with apache Qpid library and I can see the below 2 threads will keep running despite calling route stop. The issue comes is caused by "{*}SimpleMessageListenerContainer.java#SimpleMessageListenerContainer()"{*} function {code:java} protected void stopConnection() { synchronized (this.connectionLock) { this.connectionStarted = false; if (this.connection != null) { try { this.connection.stop(); } catch (Exception e) { LOG.debug("Error stopping connection. This exception is ignored.", e); } } } } {code} We should call "this.connection.close()" in doShutdown() function not doing this will only close *JMSSession* but keeps the underlying QPID Executor service and connection open to the broker. Below simple exception will replicate the issue. {code:java} CamelContext context = new DefaultCamelContext(); context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { JmsConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:5672"); getCamelContext().getRegistry().bind("qpidConnectionFactory", connectionFactory); from("sjms:topic:demo?connectionFactory=#qpidConnectionFactory") .process(exchange -> { System.out.println(exchange.getIn().getBody()); }); } }); context.start(); System.out.println("Started"); System.out.println("Stopping route"); context.stop(); Thread.sleep(100000L); // Take thread dump{code} When I take thread dump after stopping the camel context I still see below 2 threads running and I see an active connection in ActiveMQ broker also. {code:java} "QpidJMS Connection Executor: ID:e8acc451-5008-4cb2-a867-d64b9e5350d6:1" #16 prio=5 os_prio=0 cpu=0.00ms elapsed=11.30s allocated=3856B defined_classes=0 tid=0x000001f1e7cf1000 nid=0x670c waiting on condition [0x000000cd040fe000] java.lang.Thread.State: WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@11.0.15/Native Method) - parking to wait for <0x00000006241900f0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(java.base@11.0.15/LockSupport.java:194) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@11.0.15/AbstractQueuedSynchronizer.java:2081) at java.util.concurrent.LinkedBlockingQueue.take(java.base@11.0.15/LinkedBlockingQueue.java:433) at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@11.0.15/ThreadPoolExecutor.java:1054) at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.15/ThreadPoolExecutor.java:1114) at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.15/ThreadPoolExecutor.java:628) at java.lang.Thread.run(java.base@11.0.15/Thread.java:829) "AmqpProvider :(1):[amqp://localhost:5672]" #17 daemon prio=5 os_prio=0 cpu=46.88ms elapsed=9.96s allocated=8634K defined_classes=176 tid=0x000001f1e72ac000 nid=0x6298 runnable [0x000000cd041fe000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(java.base@11.0.15/Native Method) at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(java.base@11.0.15/WindowsSelectorImpl.java:357) at sun.nio.ch.WindowsSelectorImpl.doSelect(java.base@11.0.15/WindowsSelectorImpl.java:182) at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@11.0.15/SelectorImpl.java:124) - locked <0x00000006235200f8> (a io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x000000062350c728> (a sun.nio.ch.WindowsSelectorImpl) at sun.nio.ch.SelectorImpl.select(java.base@11.0.15/SelectorImpl.java:136) at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62) at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:891) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:526) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at java.lang.Thread.run(java.base@11.0.15/Thread.java:829) {code} !image-2025-04-28-16-51-43-419.png! was: The came sjms and sjms2 component cause thread to leak and the connection is kept open despite the route is stopped. I am using ActiveMQ broker with apache Qpid library and I can see the below 2 threads will keep running despite calling route stop. The issue comes is caused by "{*}SimpleMessageListenerContainer.java#SimpleMessageListenerContainer()"{*} function {code:java} protected void stopConnection() { synchronized (this.connectionLock) { this.connectionStarted = false; if (this.connection != null) { try { this.connection.stop(); } catch (Exception e) { LOG.debug("Error stopping connection. This exception is ignored.", e); } } } } {code} We should call "this.connection.close()" in doShutdown() function not doing this will only close *JMSSession* but keeps the underlying QPID Executor service and connection open to the broker. Below simple exception will replicate the issue. {code:java} CamelContext context = new DefaultCamelContext(); context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { JmsConnectionFactory connectionFactory = new JmsConnectionFactory("amqp://localhost:5672"); getCamelContext().getRegistry().bind("qpidConnectionFactory", connectionFactory); from("sjms:topic:demo?connectionFactory=#qpidConnectionFactory") .process(exchange -> { System.out.println(exchange.getIn().getBody()); }); } }); context.start(); System.out.println("Started"); System.out.println("Stopping route"); context.stop(); Thread.sleep(100000L); // Take thread dump{code} When I take thread dump after stopping the camel context I still see below 2 threads running and I see an active connection in ActiveMQ broker also. {code:java} "QpidJMS Connection Executor: ID:e8acc451-5008-4cb2-a867-d64b9e5350d6:1" #16 prio=5 os_prio=0 cpu=0.00ms elapsed=11.30s allocated=3856B defined_classes=0 tid=0x000001f1e7cf1000 nid=0x670c waiting on condition [0x000000cd040fe000] java.lang.Thread.State: WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@11.0.15/Native Method) - parking to wait for <0x00000006241900f0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(java.base@11.0.15/LockSupport.java:194) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@11.0.15/AbstractQueuedSynchronizer.java:2081) at java.util.concurrent.LinkedBlockingQueue.take(java.base@11.0.15/LinkedBlockingQueue.java:433) at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@11.0.15/ThreadPoolExecutor.java:1054) at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.15/ThreadPoolExecutor.java:1114) at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.15/ThreadPoolExecutor.java:628) at java.lang.Thread.run(java.base@11.0.15/Thread.java:829) "AmqpProvider :(1):[amqp://localhost:5672]" #17 daemon prio=5 os_prio=0 cpu=46.88ms elapsed=9.96s allocated=8634K defined_classes=176 tid=0x000001f1e72ac000 nid=0x6298 runnable [0x000000cd041fe000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(java.base@11.0.15/Native Method) at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(java.base@11.0.15/WindowsSelectorImpl.java:357) at sun.nio.ch.WindowsSelectorImpl.doSelect(java.base@11.0.15/WindowsSelectorImpl.java:182) at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@11.0.15/SelectorImpl.java:124) - locked <0x00000006235200f8> (a io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x000000062350c728> (a sun.nio.ch.WindowsSelectorImpl) at sun.nio.ch.SelectorImpl.select(java.base@11.0.15/SelectorImpl.java:136) at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62) at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:891) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:526) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at java.lang.Thread.run(java.base@11.0.15/Thread.java:829) {code} !image-2025-04-28-16-51-43-419.png! > Camel SJMS & SJMS2 component cause thread leak when the route is stopped. > ------------------------------------------------------------------------- > > Key: CAMEL-22026 > URL: https://issues.apache.org/jira/browse/CAMEL-22026 > Project: Camel > Issue Type: Bug > Components: camel-sjms, camel-sjms2 > Affects Versions: 3.22.3 > Environment: Java 17 > Tried with Camel 3.14.9, Latest 3.x and 4.x issue is seen even in latest build > ActiveMQ broker 6.x > > Reporter: Kartik > Priority: Major > Attachments: image-2025-04-28-16-51-43-419.png > > > The camel sjms and sjms2 component cause thread to leak and the connection is > kept open despite the route is stopped. > I am using ActiveMQ broker with apache Qpid library and I can see the below 2 > threads will keep running despite calling route stop. > The issue comes is caused by > "{*}SimpleMessageListenerContainer.java#SimpleMessageListenerContainer()"{*} > function > {code:java} > protected void stopConnection() { > synchronized (this.connectionLock) { > this.connectionStarted = false; > if (this.connection != null) { > try { > this.connection.stop(); > } catch (Exception e) { > LOG.debug("Error stopping connection. This exception is > ignored.", e); > } > } > } > } {code} > We should call "this.connection.close()" in doShutdown() function not doing > this will only close *JMSSession* but keeps the underlying QPID Executor > service and connection open to the broker. > Below simple exception will replicate the issue. > {code:java} > CamelContext context = new DefaultCamelContext(); context.addRoutes(new > RouteBuilder() > { > @Override > public void configure() throws Exception > { > JmsConnectionFactory connectionFactory = new > JmsConnectionFactory("amqp://localhost:5672"); > getCamelContext().getRegistry().bind("qpidConnectionFactory", > connectionFactory); > from("sjms:topic:demo?connectionFactory=#qpidConnectionFactory") > .process(exchange -> { > System.out.println(exchange.getIn().getBody()); > }); > } > }); > context.start(); > System.out.println("Started"); > System.out.println("Stopping route"); > context.stop(); > Thread.sleep(100000L); > // Take thread dump{code} > When I take thread dump after stopping the camel context I still see below 2 > threads running and I see an active connection in ActiveMQ broker also. > {code:java} > "QpidJMS Connection Executor: ID:e8acc451-5008-4cb2-a867-d64b9e5350d6:1" #16 > prio=5 os_prio=0 cpu=0.00ms elapsed=11.30s allocated=3856B defined_classes=0 > tid=0x000001f1e7cf1000 nid=0x670c waiting on condition [0x000000cd040fe000] > java.lang.Thread.State: WAITING (parking) at > jdk.internal.misc.Unsafe.park(java.base@11.0.15/Native Method) - > parking to wait for <0x00000006241900f0> (a > java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) > at > java.util.concurrent.locks.LockSupport.park(java.base@11.0.15/LockSupport.java:194) > at > java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@11.0.15/AbstractQueuedSynchronizer.java:2081) > at > java.util.concurrent.LinkedBlockingQueue.take(java.base@11.0.15/LinkedBlockingQueue.java:433) > at > java.util.concurrent.ThreadPoolExecutor.getTask(java.base@11.0.15/ThreadPoolExecutor.java:1054) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@11.0.15/ThreadPoolExecutor.java:1114) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@11.0.15/ThreadPoolExecutor.java:628) > at java.lang.Thread.run(java.base@11.0.15/Thread.java:829) > "AmqpProvider :(1):[amqp://localhost:5672]" #17 daemon prio=5 os_prio=0 > cpu=46.88ms elapsed=9.96s allocated=8634K defined_classes=176 > tid=0x000001f1e72ac000 nid=0x6298 runnable [0x000000cd041fe000] > java.lang.Thread.State: RUNNABLE at > sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(java.base@11.0.15/Native > Method) at > sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(java.base@11.0.15/WindowsSelectorImpl.java:357) > at > sun.nio.ch.WindowsSelectorImpl.doSelect(java.base@11.0.15/WindowsSelectorImpl.java:182) > at > sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@11.0.15/SelectorImpl.java:124) > - locked <0x00000006235200f8> (a > io.netty.channel.nio.SelectedSelectionKeySet) - locked > <0x000000062350c728> (a sun.nio.ch.WindowsSelectorImpl) at > sun.nio.ch.SelectorImpl.select(java.base@11.0.15/SelectorImpl.java:136) > at > io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62) > at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:891) > at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:526) at > io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) > at > io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) > at java.lang.Thread.run(java.base@11.0.15/Thread.java:829) {code} > > !image-2025-04-28-16-51-43-419.png! -- This message was sent by Atlassian Jira (v8.20.10#820010)