ActiveMQ embedded bridge to Camel JMS bridge

428 views Asked by At

I have an old application which handle JMS messages with ActiveMQ 5.8.0 and some JNDI remote topic connected to this ActiveMQ.

I have a connector like that :

<bean class="org.apache.activemq.network.jms.JmsConnector">
    <property name="outboundTopicConnectionFactory" ref="jmsConnectionFactoryTo" />
    <property name="outboundClientId" value="${remote.clientId}" />
    <property name="jndiOutboundTemplate" ref="jndiTemplateTo" />
    <property name="preferJndiDestinationLookup" value="true" />
    <property name="inboundTopicBridges">
        <list>
            <bean class="org.apache.activemq.network.jms.InboundTopicBridge">
                <property name="inboundTopicName" value="${remote.topic.to}"/> 
                <property name="localTopicName" value="${local.topic.to}"/>
                <property name="consumerName" value="${remote.consumer.name}"/>
                <property name="selector" value="${remote.selector}"/>
            </bean>
        </list>
    </property>
</bean>

It works great, but now, for some technical reasons (strict JMS 1.1), I need to use "ConnectionFactory" instead of "TopicConnectionFactory". With the actual configuration, I'm stuck because ActiveMQ seems to use "TopicConnectionFactory" instead of "ConnectionFactory", and my new class "MyConnectionFactoryImpl" implements "ConnectionFactory" now :

nested exception is org.springframework.beans.ConversionNotSupportedException: 
Failed to convert property value of type 'com.webmethods.jms.impl.MyConnectionFactoryImpl' 
to required type 'javax.jms.TopicConnectionFactory' 
for property 'outboundTopicConnectionFactory'; 
nested exception is java.lang.IllegalStateException: 
Cannot convert value of type [com.webmethods.jms.impl.MyConnectionFactoryImpl] 
to required type [javax.jms.TopicConnectionFactory] for property 'outboundTopicConnectionFactory': 
no matching editors or conversion strategy found

In "org.apache.activemq.network.jms.JmsConnector" class, it use everywhere "TopicConnectionFactory", which is not recommended anymore in JMS 1.1.

EDIT : According to @Justin Bertram, I need to use Camel instead of ActiveMQ embedded bridge. But I can't find any example of XML configuration which I can use to replace my actual two beans JMSConnector. Which is the simple way to do this keeping my XML config files ?

2

There are 2 answers

0
Doug Grove On

I would think that having your code return a TopicConnectionFactory would be the simplest solution. Even the JMS 2.0 specification provides the TopicConnectionFactory. No matter what version of ActiveMQ you are using, you certainly have the option of using the TopicConnectionFactory in your code and providing that to your bridge.

Note that the Camel route:

   <camelContext xmlns="http://camel.apache.org/schema/spring">
      <route>
         <from uri="mqseries:Foo.Bar"/>
         <to uri="activemq:Cheese"/>
      </route>
   </camelContext>

has no error handling. For example, if the 'to' endpoint is down, this route will read from the 'from' endpoint and just throw the messages on the floor. Furthermore, if the 'to' component is not configured to use a caching/pooling connection factory, then a new JMS connection will be created for each message sent. This has poor performance and can result in many sockets in the TIME_WAIT state. Bottom line - beware trivial Camel routes.

3
Justin Bertram On

As the documentation for the JMS to JMS Bridge (i.e. org.apache.activemq.network.jms.JmsConnector) states:

ActiveMQ provides bridging functionality to other JMS providers that implement the JMS 1.0.2 and above specification.

In other words, the whole goal of the JMS to JMS Bridge is to use the JMS 1.0.2 interface(s). Changing it so that it only used JMS 1.1 would defeat the purpose.

The documentation also states that you should use Camel instead of the JMS to JMS Bridge:

Warning, try Camel first!

Note that we recommend you look at using Apache Camel for bridging ActiveMQ to or from any message broker (or indeed any other technology, protocol or middleware) as its much easier to:

  • keep things flexible; its very easy to map different queue/topic to one or more queues or topics on the other provider
  • perform content based routing, filtering and other Enterprise Integration Patterns
  • allows you to work with any technology, protocol or middleware, not just JMS providers

Therefore I recommend you use Camel instead of org.apache.activemq.network.jms.JmsConnector.