You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Timothy Bish (JIRA)" <ji...@apache.org> on 2014/07/08 22:12:05 UTC

[jira] [Commented] (AMQ-5262) ActiveMQ hangs on shutdown when JMS Bridge is created

    [ 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)