Question

I need to define a route which reads message (has an xml) from a Topic and unmarshals it to a java bean.

Earlier i was using spring JmsTemplate for managing connectionFactory for the topic and my route looked something like this (and it worked fine) The message converter essetially returns the TextMessage instance in the fromMessage() method

JaxbDataFormat dataFormat = new JaxbDataFormat();
dataFormat.setContextPath("com.somepath.xml");

from("jms:topic:myTopic?transacted=true&connectionFactory=myJmsConnectionFactory&messageConverter=#myMessageConverter")
 .transacted()
 .unmarshal(dataFormat)
 .routeId("myRouteId")

Now, instead of a JmsTemplate, i am using org.springframework.jms.listener.DefaultMessageListenerContainer to connect to this durable topic.

(Also because it supports asynchronous mode)

For this i wrote my own message listener which implements javax.jms.MessageListener and i read the message in onMessage(). But i cannot return a TextMessage from here like the way i used to do when is used JmsTemplate.

I don't know how can i configure this in the route definition so that it still supports unmarshalling?

Was it helpful?

Solution

I tried a lot of things and the solution is really simple, there is no need to use `org.springframework.jms.listener.DefaultMessageListenerContainer, instead, all we need to do is to define a connectionFactory which in my case was the myJmsConnectionFactory instance defined as the following in the spring xml

<bean id="myJmsConnectionFactory"        class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiTemplate" ref="myJndiTemplate" />
            <property name="jndiName" value="TopicConnectionFactory" />
            <property name="lookupOnStartup" value="false" />
            <property name="proxyInterfaces" value="javax.jms.ConnectionFactory" />
            <property name="cache" value="true" />
</bean>

This connection factory uses a jndi template which helps in the jndi look up of remote objects. This is defined as

<bean id="myJndiTemplate" class="org.springframework.jndi.JndiTemplate">
            <property name="environment">
                <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
                    <property name="location" value="file:///opt/test/jndi.properties" />
                </bean>
            </property>
</bean>

In the route definition, i just use this connection factory to lookup the remote topic. By default camel registers a message listener when you connect to a jms topic and you don't have to specify one (you can but i didn't need to :))

JaxbDataFormat dataFormat = new JaxbDataFormat();
dataFormat.setContextPath("com.somepath.xml");

from("jms:topic:myTopic?transacted=true&connectionFactory=myJmsConnectionFactory")
 .transacted()
 .unmarshal(dataFormat)
 .routeId("myRouteId")
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top