View Javadoc

1   /*
2    * $Id: ActiveMqJmsConnector.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.providers.jms.activemq;
12  
13  import org.mule.providers.ConnectException;
14  import org.mule.providers.jms.JmsConnector;
15  import org.mule.providers.jms.xa.ConnectionFactoryWrapper;
16  
17  import java.lang.reflect.Method;
18  import java.lang.reflect.Proxy;
19  
20  import javax.jms.Connection;
21  
22  /**
23   * ActiveMQ 4.x-specific JMS connector.
24   */
25  public class ActiveMqJmsConnector extends JmsConnector
26  {
27      /**
28       * Constructs a new ActiveMqJmsConnector.
29       */
30      public ActiveMqJmsConnector()
31      {
32          setEagerConsumer(false);
33          // TODO MULE-1409 better support for ActiveMQ 4.x temp destinations
34      }
35  
36      /**
37       * Will additionally try to cleanup the ActiveMq connection, otherwise there's a deadlock on shutdown.
38       */
39      protected void doDisconnect() throws ConnectException
40      {
41          try
42          {
43              Connection connection = getConnection();
44              if (connection == null)
45              {
46                  return;
47              }
48  
49              final Class clazz = connection.getClass();
50              Method cleanupMethod;
51              if (Proxy.isProxyClass(clazz))
52              {
53                  ConnectionFactoryWrapper.ConnectionInvocationHandler handler =
54                          (ConnectionFactoryWrapper.ConnectionInvocationHandler) Proxy.getInvocationHandler(connection);
55                  // this is really an XA connection, bypass the java.lang.reflect.Proxy as it
56                  // can't delegate to non-interfaced methods (like proprietary 'cleanup' one)
57                  // TODO check if CGlib will manage to enhance the AMQ connection class,
58                  // there are no final methods, but a number of private ones, though
59                  connection = (Connection) handler.getTargetObject();
60                  Class realConnectionClass = connection.getClass();
61                  cleanupMethod = realConnectionClass.getMethod("cleanup", null);
62              }
63              else
64              {
65                  cleanupMethod = clazz.getMethod("cleanup", null);
66              }
67  
68              try
69              {
70                  if (cleanupMethod != null)
71                  {
72                      cleanupMethod.invoke(connection, null);
73                  }
74              }
75              finally
76              {
77                  connection.close();
78              }
79          }
80          catch (Exception e)
81          {
82              throw new ConnectException(e, this);
83          }
84          finally
85          {
86              setConnection(null);
87          }
88      }
89  }