Skip to main content

Using JNDI managed JMS objects with Apache CAMEL

Apache CAMEL uses Spring JMS to work with JMS Queues or Topics. Evidently, we will need Spring to configure and use JMS capabilities provided by CAMEL.
Details about how to implement JMS based routes using Apache CAMEL can be found in the CAMEL documentation.

However, the documentation leaves a lot to be figured out. In a typical Java EE container, it is usually a good idea to abstract the underlying JMS resources by using JNDI. We can use the below configuration to achieve that. This configuration is tested in Websphere environment, but should work in any JEE container.
  • Create a JMS queue connection factory in the JNDI registry. CAMEL configuration will be able to use only one queue connection factory, even if we have more than one.
  • Create one or more JMS queue or topics, in the JNDI registry, as required.
The above two steps are related to generic JNDI configuration for JMS resources. Now we come to the setup required for making these JMS resources work with CAMEL routes.
  • First, we create resource reference for the queue connection factory. This can be configured in web.xml or ejb-jar.xml file, depending upon whether we are working with a web or a JEE module.
  • Next we shall inject the queue connection factory into our spring context using JEE namespace as below. jee: tags refer to xmlns:jee="http://www.springframework.org/schema/jee". The queue connection factory can be injected into spring context as below
                   <jee:jndi-lookup id="jmsQCF" jndi-name="jms/TestQCF"/>
  • This brings us to an important tool available in spring suite, that helps us in referring queues and topics aka. destinations, defined using JNDI. Referring the CAMEL documentation for JMS component, we find that the JMS component supports a destination resolver. Spring provides a destination resolver implementation for destinations defined using JNDI. The destination resolver can be injected in spring context as
                <bean id="destResolver" 
                          class="org.springframework.jms.support.destination.JndiDestinationResolver"/>
  • Once queue connection factory and destination resolver are available in spring context, we can now inject these into CAMEL JMS Configuration. This is akin to setting up JMSTemplate when using Spring JMS. We can also configure additional optional properties such as concurrent consumers, which define the number of listener threads that will run, if JMS consumer component is used in a route.
             <bean id="jmsCamelConfig"
                     class="org.apache.camel.component.jms.JmsConfiguration">
                   <property name="connectionFactory" ref="jmsConnectionFactory"/>
                   <property name="destinationResolver" ref="jndiDestinationResolver"/>
                  <property name="concurrentConsumers" value="10"/>
              </bean>

  • The above configuration brings us to a point where we have the capability to set up CAMEL JMS component to use the configuration we have defined in previous step
           <bean id="jmsx" class="org.apache.camel.component.jms.JmsComponent">
               <property name="configuration" ref="jmsCamelConfig"/>
           </bean>

Once this configuration is complete, we can use CAMEL jms component as defined in the CAMEL documentation. All we need to do is refer JNDI names for the queues and topics we use in the routes.

This post is aimed at preventing severe heartburn and wasted man hours, trying to piece together the correct configuration by going through multiple different documentation.

References:

Comments

Popular posts from this blog

Catch hold of that Exception and hide that stacktrace!!!

E xceptions happen!!! Rules are to be followed, too. Time and again, Java developers are told the golden rule to catch specific exceptions and not to catch the generic Exception. The thought process behind that is, applications should not catch runtime exceptions. This is apt as runtime exceptions are an indicator of "bugs" in the code. However, blindly following rules, as always, can have unexpected consequences. If you are developing services that are to be exposed over the wire, it is always a good idea to break this rule and "catch that Exception". Instead, follow the below principles: Service methods should implement a generic Exception block, along with catching declared exceptions, thrown from inner layers of the code.  If needed, the service can throw another exception back to the client. What's important is that we create a new Exception instance to be thrown, along with relevant message for the client. The service can log stacktrace for the E...

Container ready spring boot application

Spring boot applications are now ubiquitous. The usual way to build one is to create an uber jar. At the same time, Docker allows us to build self reliant containers which are unaffected by the underlying server architecture or neighboring applications or their dependencies. Spring boot applications can also run in docker containers.  However running an uber jar inside a container fails to satisfy an important goal. That of high speed build and deployment. An uber jar is a heavy weight entity. That will make docker image heavy and slow to build. Here's a step by step solution, which leverages docker layer caching feature for faster builds with all spring boot goodness. We will use Maven to build a deployment structure for our docker image that allows fast deployments. Step 1: Create a spring boot application with only the SpringBootApplication and Configuration classes, such as one for REST configuration package scanning, one for JPA etc. Most often this wil...