View Javadoc

1   /*
2    * $Id: ActiveMQJmsConnector.java 10803 2008-02-14 13:31:25Z holger $
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.transport.jms.activemq;
12  
13  import org.mule.transport.ConnectException;
14  import org.mule.transport.jms.JmsConnector;
15  import org.mule.transport.jms.xa.ConnectionInvocationHandler;
16  import org.mule.util.ClassUtils;
17  
18  import java.lang.reflect.Method;
19  import java.lang.reflect.Proxy;
20  
21  import javax.jms.Connection;
22  import javax.jms.ConnectionFactory;
23  
24  /**
25   * ActiveMQ 4.x-specific JMS connector.
26   */
27  public class ActiveMQJmsConnector extends JmsConnector
28  {
29      public static final String ACTIVEMQ_CONNECTION_FACTORY_CLASS = "org.apache.activemq.ActiveMQConnectionFactory";
30      public static final String DEFAULT_BROKER_URL = "vm://localhost?broker.persistent=false&broker.useJmx=false";
31  
32      private String brokerURL = DEFAULT_BROKER_URL;
33  
34      /**
35       * Constructs a new ActiveMQJmsConnector.
36       */
37      public ActiveMQJmsConnector()
38      {
39          setEagerConsumer(false);
40          // TODO MULE-1409 better support for ActiveMQ 4.x temp destinations
41      }
42  
43      protected ConnectionFactory getDefaultConnectionFactory()
44      {
45          try
46          {
47              ConnectionFactory connectionFactory = (ConnectionFactory)
48                      ClassUtils.instanciateClass(ACTIVEMQ_CONNECTION_FACTORY_CLASS, new Object[]{getBrokerURL()});
49              applyVendorSpecificConnectionFactoryProperties(connectionFactory);
50              return connectionFactory;
51          }
52          catch (Exception e)
53          {
54              handleException(e);
55              return null;
56          }
57      }
58  
59      protected void applyVendorSpecificConnectionFactoryProperties(ConnectionFactory connectionFactory)
60      {
61          try
62          {
63              Method getRedeliveryPolicyMethod = connectionFactory.getClass().getMethod("getRedeliveryPolicy", new Class[]{});
64              Object redeliveryPolicy = getRedeliveryPolicyMethod.invoke(connectionFactory, new Object[]{});
65              Method setMaximumRedeliveriesMethod = redeliveryPolicy.getClass().getMethod("setMaximumRedeliveries", new Class[]{Integer.TYPE});
66              setMaximumRedeliveriesMethod.invoke(redeliveryPolicy, new Object[]{new Integer(getMaxRedelivery())});
67          }
68          catch (Exception e)
69          {
70              logger.error("Can not set MaxRedelivery parameter to RedeliveryPolicy " + e);
71          }
72      }
73  
74      /**
75       * Will additionally try to cleanup the ActiveMq connection, otherwise there's a deadlock on shutdown.
76       */
77      protected void doDisconnect() throws ConnectException
78      {
79          try
80          {
81              Connection connection = getConnection();
82              if (connection == null)
83              {
84                  return;
85              }
86  
87              final Class clazz = connection.getClass();
88              Method cleanupMethod;
89              if (Proxy.isProxyClass(clazz))
90              {
91                  ConnectionInvocationHandler handler =
92                          (ConnectionInvocationHandler) Proxy.getInvocationHandler(connection);
93                  // this is really an XA connection, bypass the java.lang.reflect.Proxy as it
94                  // can't delegate to non-interfaced methods (like proprietary 'cleanup' one)
95                  // TODO check if CGlib will manage to enhance the AMQ connection class,
96                  // there are no final methods, but a number of private ones, though
97                  connection = (Connection) handler.getTargetObject();
98                  Class realConnectionClass = connection.getClass();
99                  cleanupMethod = realConnectionClass.getMethod("cleanup", (Class[])null);
100             }
101             else
102             {
103                 cleanupMethod = clazz.getMethod("cleanup", (Class[])null);
104             }
105 
106             try
107             {
108                 if (cleanupMethod != null)
109                 {
110                     cleanupMethod.invoke(connection, (Object[])null);
111                 }
112             }
113             finally
114             {
115                 connection.close();
116             }
117         }
118         catch (Exception e)
119         {
120             throw new ConnectException(e, this);
121         }
122         finally
123         {
124             setConnection(null);
125         }
126     }
127 
128     public String getBrokerURL()
129     {
130         return brokerURL;
131     }
132 
133     public void setBrokerURL(String brokerURL)
134     {
135         this.brokerURL = brokerURL;
136     }
137 }