activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Timothy Bish (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (AMQ-5262) ActiveMQ hangs on shutdown when JMS Bridge is created
Date Tue, 08 Jul 2014 20:12:05 GMT

    [ https://issues.apache.org/jira/browse/AMQ-5262?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14055421#comment-14055421
] 

Timothy Bish commented on AMQ-5262:
-----------------------------------

It does seems like there should be a close there, although probably after the connectionService
is stopped to prevent any attempts at reconnect from contending with the close.  

In reality we recommend using Camel as the Bridging technology as it has proven itself to
be far better at doing this sort of thing.  See: http://activemq.apache.org/jms-to-jms-bridge.html

> ActiveMQ hangs on shutdown when JMS Bridge is created
> -----------------------------------------------------
>
>                 Key: AMQ-5262
>                 URL: https://issues.apache.org/jira/browse/AMQ-5262
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.9.0, 5.9.1, 5.10.0
>            Reporter: Peter Minearo
>            Priority: Minor
>
> We are having a problem with ActiveMQ hanging on shutdown.  Here is the scenario, we
have a stand alone application that runs an embedded ActiveMQ which creates a JMS Queue Bridge
via Spring configs. When we call shutdown, the TCPTransport that connects the JMS Queue Bridge
does not shutdown, it hangs on java.net.SocketInputStream.socketRead0(). 
> {noformat}
> java.lang.Thread.State: RUNNABLE
> 	at java.net.SocketInputStream.socketRead0(Native Method)
> 	at java.net.SocketInputStream.read(SocketInputStream.java:129)
> 	at org.apache.activemq.transport.tcp.TcpBufferedInputStream.fill(TcpBufferedInputStream.java:50)
> 	at org.apache.activemq.transport.tcp.TcpTransport$2.fill(TcpTransport.java:604)
> 	at org.apache.activemq.transport.tcp.TcpBufferedInputStream.read(TcpBufferedInputStream.java:58)
> 	at org.apache.activemq.transport.tcp.TcpTransport$2.read(TcpTransport.java:589)
> 	at java.io.DataInputStream.readInt(DataInputStream.java:370)
> 	at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.java:275)
> 	at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTransport.java:221)
> 	at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:213)
> 	at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:196)
> 	at java.lang.Thread.run(Thread.java:662)
> {noformat}
> Digging around on the forums and the issue tracker, the work around seems to add a parameter
to the URI (Ex - tcp://localhost:60606?daemon=true).  
> According to this StackOverflow posting (http://stackoverflow.com/questions/2213340/what-is-daemon-thread-in-java)
which quotes from Java Concurrency in Practice 
> * When a new thread is created it inherits the daemon status of its parent.
> * Normal thread and daemon threads differ in what happens when they exit. When the JVM
halts any remaining daemon threads are abandoned: **finally blocks are not executed**, stacks
are not unwound - JVM just exits. Due to this reason daemon threads should be used sparingly
and it is dangerous to use them for tasks that might perform any sort of I/O.
> So, making the Socket that connects the JMS Queue Bridge a Daemon thread, seems to be
the wrong solution.  
> I was trying to debug the initialization of ActiveMQ, and noticed the org.apache.activemq.network.jms.JmsConnector
class has a stop() method on it.  I believe this class creates the connection for the JMS
Bridge, right?  If so, the stop method does not seem to shutdown the connection properly.

> {code}
> public void stop() throws Exception {
>         if (started.compareAndSet(true, false)) {
>             ThreadPoolUtils.shutdown(connectionSerivce);
>             connectionSerivce = null;
>             for (DestinationBridge bridge : inboundBridges) {
>                 bridge.stop();
>             }
>             for (DestinationBridge bridge : outboundBridges) {
>                 bridge.stop();
>             }
>             LOG.info("JMS Connector {} stopped", getName());
>         }
>         
> }
> {code}
> The question I have is why is the stop() method relying on the ThreadPoolUtils.shutdown(connectionSerivce)
and NOT calling close() on the Connections first? For example:
> {code}
> public void stop() throws Exception {
>         if (started.compareAndSet(true, false)) {
> 			foreignConnection.get().close();
> 			localConnection.get().close();
> 			
>             ThreadPoolUtils.shutdown(connectionSerivce);
>             connectionSerivce = null;
>             for (DestinationBridge bridge : inboundBridges) {
>                 bridge.stop();
>             }
>             for (DestinationBridge bridge : outboundBridges) {
>                 bridge.stop();
>             }
>             LOG.info("JMS Connector {} stopped", getName());
>         }
>         
> }
> {code}
> It was a little difficult to follow the code, so I may be missing something.  BUT shouldn't
the connections close first?  Or am I looking in the wrong place.  
> I have created a small project that creates this scenario.
> https://github.com/pminearo/activemq-shutdown-bug.git
> This was done with ActiveMQ 5.9.  Though, since this bug has been around for quite some
time, it most likely is still in 5.10, 5.11, and 6.0.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Mime
View raw message