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

Peter Minearo commented on AMQ-5262:
------------------------------------

The JMS Bridge so far has been working great.  The only issue we have seen is 
this hanging resource.  So, cleaning up the resources properly would fix the 
issue and make the use of Camel no longer a needed option.  Are there more 
technical reasons to not use the JMS Bridge the way it is set up in the Test 
project I included?  Is this functionality a legacy spec and no longer 
supported?  Did it change in 6.0? etc? 


> 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
>             Fix For: 5.11.0
>
>
> 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)

Reply via email to