Which HornetQ libraries i need for JMS client? - spring

I have a standalone hornetq server and a JMS client working with it! With respect to hornetq user-manual i should only add jnp-client.jar and jms.jar to client classpath. But when i trying use hornetq server (produce and consume messages), several ClassNotFoundExceptions thrown, so i forced adding these jar files to my client classpath:
1. jms
2. jnp-client
3. hornetq-jms-client
4. netty
5. hornetq-core-cilent
6. jboss-common
Am i using Hornetq core client instead of jms client?? What jar files i really need for jms client??
My applicationContext.xml:
<!-- JndiTemplate -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
<prop key="java.naming.provider.url">jnp://localhost:1099</prop>
</props>
</property>
</bean>
<!-- Connection Factory -->
<bean id="hornetqConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="/ConnectionFactory" />
</bean>
<!-- Destionation -->
<bean id="annotationDeleteCommandDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jndiTemplate"/>
<property name="jndiName" value="/queue/command/annotation/deleteQueue" />
</bean>
<!-- Message Listener -->
<bean id="annotationMessageHandler" class="command.messaging.handler.annotation.AnnotationMessageHandler">
<property name="annotationService" ref="annotationService"/>
</bean>
<!-- Message Listener Container -->
<bean id="annotationDeleteCommandMsgListenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer"
p:connectionFactory-ref="hornetqConnectionFactory"
p:destination-ref="annotationDeleteCommandDestination"
p:cacheLevelName="CACHE_CONSUMER"
p:messageListener-ref="annotationDeleteCommandMessageHandler"
p:concurrentConsumers="10"
p:maxConcurrentConsumers="50"
p:receiveTimeout="5000"
p:idleTaskExecutionLimit="10
p:idleConsumerLimit="5" />
<!-- Message Producer -->
<bean id="messageSender" class="command.messaging.sender.MessageSender">
<property name="connectionFactory" ref="hornetqConnectionFactory" />
</bean>

HornetQ-JMS-Client is an adapter for the HornetQ-Core-Client that exposes the JMS API.
So you need them both.
And HornetQ-Core-Client needs netty internally, so you need that one, too.
Not sure about jboss-common. You need some logging dependency, but I don't remember exactly which one.
Please note that, unlike SOAP, JMS is an API, not a protocol. The rest of the application is independent of the API provider, but you need the correct client libraries that understand the custom protocol that your JMS Server uses. So you can't use the HornetQ JMS Client to connect to ActiveMQ, for example.

Per the docs...
If you are using just a pure HornetQ Core client (i.e. no JMS) then you need hornetq-core-client.jar, hornetq-commons.jar, and netty.jar.
If you are using JMS on the client side, then you will also need to include hornetq-jms-client.jar and jboss-jms-api.jar.
These refer to files in the standalone hornetq download's lib directory.
I needed to add jnp-client.jar to avoid a CNF too.

Related

Using ActiveMQ/JMS on Tomcat server?

We have a Spring based web application deployed in Tomcat. The web application uses Spring's JmsTemplate and DefaultMessageListenerContainer to produce and consume messages respectively. Our JMS provider is ActiveMQ "Classic" and we have used ActiveMQ client libraries to establish a connection with the native broker. We have used PooledConnectionFactory from the activemq-pool library. Since it's a Spring web application we have defined the connection factory bean and wired the connectionFactory into JmsTemplate and DefaultMessageListenerContainer beans respectively. We are assuming the pooling would be driven by Spring through the connection factory.
The behavior we are seeing is the JMS sessions are being created/destroyed continuously. Under load the application would stop consuming the messages.
After reading different articles we are trying to understand the role of JCA JMS. Can anybody suggest implementing JMS through JCA would resolve the issue and to enlist JMS as an XA resource to maintain the connections and sessions through JCA Adapters.
In our Spring JMS web application and Tomcat server we have used both the ActiveMQ PooledConnectionFactory and ActiveMQConnectionFactory from ActiveMQ client libraries. We see the sessions are being created/destroyed frequently and this stops the JMS client from consuming messages.
The below snippet of the Spring beans how we have configured the Spring JmsTemplate and DefaultMessageListenerContainer beans wired in with the connectionFactory.
<!--bean id="jmsQueueConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="ssl://localhost:61616"/>
<property name="trustAllPackages" value="true"/>
</bean-->
<bean id="jmsQueueConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="ssl://localhost:61616"/>
<property name="trustAllPackages" value="true"/>
</bean>
</property>
<property name="maxConnections" value="5"/>
<property name="maximumActiveSessionPerConnection" value="400"/>
</bean>
<bean id="dmDefaultMessageListenerContainer" class="com.crsoftwareinc.crs.core.jmsListener.DMDefaultMessageListenerContainer">
<property name="autoStartup" value="false"/>
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="5" />
<property name="cacheLevelName" value="CACHE_NONE"/>
<property name="connectionFactory" ref="jmsQueueConnectionFactory" />
<property name="sessionTransacted" value="true"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
<property name="sessionTransacted" value="true"/>
</bean>
We are looking for a work around how could we use JMS with ActiveMQ in Spring Web application in production deployments where the connections and sessions are maintained seamlessly?

For camel JmsConfiguration Spring cachingconnectionfactory can be used with JndiObjectFactoryBean inside websphere Appserver

My application is running under Websphere Application server and uses apache camel for message routing. My QueueConnectionFactories and Queues are created as JMS resources in the Appserver with jndi pointing to WebsphereMQ Queue Manager. Can I use SpringCachingConnectionFactory for better performance inside JEE container like WAS with JNDI. Following spring config:
<bean id="jmsDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
</bean>
<bean id="myJndiObjectFacory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jms/MyQCF"/>
</bean>
<bean id="myJmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="myJndiObjectFacory"/>
<property name="transactionManager" ref="txManager"/>
<property name="destinationResolver" ref="jmsDestinationResolver"/>
Will above code have same performance as of spring CachingConnectionFactory ?
or
Is it possible to use CachingConnectionFactory with Jndi lookup in websphere JEE container?

Spring + JMS + ActiveMQ without dependency on ActiveMQ

I'm trying to build a MQ producer that sends a message to an ActiveMQ queue. The thing is that I don't want the implementation to be specific for ActiveMQ. I actually am doing the ActiveMQ sending in dev environment, and in production the application server will use something else. I'm planning to use Maven to create 2 profiles that will filter resources based on the given profile.
I started playing with JNDI, but I'm stuck... I tried a lot of options, but none are viable.
For now, my spring config xml is like this:
<jee:jndi-lookup id="mqConnectionFactory" jndi-name="java:comp/env/jms/mqConnectionFactory" />
<bean id="jmsJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</prop>
<prop key="java.naming.provider.url">vm://localhost</prop>
</props>
</property>
</bean>
<bean id="ismeJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestination" ref="ismeJmsDestination"/>
<property name="connectionFactory" ref="mqConnectionFactory"/>
</bean>
<bean id="ismeJmsDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref="jmsJndiTemplate"/>
<property name="jndiName" value="dynamicQueues/FOO.BAR"/>
</bean>
mqConnectionFactory cannot be found because I didn't add it in JNDI. I don't know how to add it actually, as this is not a webapp, so no context.xml.
Can someone help me in the right direction?
Whatever broker implementation you chose, you need to have the corresponding client library in your classpath. The JMS API is just an API, you need an actual implementation to connect to the broker of your choice.
Say you want to connect to ActiveMQ in development and to whatever JMS implementation in production. You can isolate those two config in separate profiles and make the activeMQ dependency an optional dependency in Maven.

Handle activemq-spring connection errors

I have configured (with spring) my application to listen to a jms que with activemq, and everything works fine.
My activemq server is installed on another server and sometime it can go offline and I would like to handle the connection error. Is that possible?
Here is my spring configuration
<amq:connectionFactory id="jmsFactory" brokerURL="tcp://xxx.xxx.xxx.xxx:61616" />
<bean id="messageConverter" class="com.unic.thesting.main.jms.message.TheStingMessageConverter" scope="tenant"/>
<jms:listener-container concurrency="10" connection-factory="thestingJmsFactory" destination-type="queue" message-converter="thestingMessageConverter">
<jms:listener destination="in" ref="orderStatusConsumer" method="consume"/>
</jms:listener-container>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate" scope="tenant">
<property name="messageConverter" ref="messageConverter" />
<property name="connectionFactory">
<bean class="org.springframework.jms.connection.SingleConnectionFactory" scope="tenant">
<property name="targetConnectionFactory">
<ref local="jmsFactory" />
</property>
</bean>
</property>
</bean>
The DefaultMessageListenerContainer which gets registered when you use ` handles recovering connections to the JMS provider if it gets dropped for any reason (it by default retries every 5 seconds until the connection is restored), so you don't have to do anything on the listener front.
On the sending side with jmsTemplate, you would receive a runtime org.springframework.jms.JmsException if there is any issues in sending a message. You should be able to catch it for any custom processing

Can Apache Camel connect to an ActivationSpec in WebSphere?

In the past, I've been able to successfully connect Camel to a Message Queue exposed as a JNDI resource in WebSphere [1]. This works with a Connection Factory. Great.
Now today, I have a situation where sys admins have only provided an Activation Specification. No Connection Factory. Here's what we've got:
SIBus name: ________
Provider endpoint: ________
Topic space: Default.Topic.Space
Messaging Engine Name: ________
Topic name: ________
From what I've read, Activation Specification is intended for MDBs (Message Driven Beans). But Spring has some APIs for ActivationSpec -- DefaultJmsActivationSpecFactory, for example -- so I'm optimistic I can configure Camel / Spring to work with an Activation Specification. I'm not sure that it matters, but this is an SIBus with a foreign bus.
My question is:
Has anyone had any luck configuring Camel to communicate with an Activation Specification?
See also:
What's the difference between ActivationSpec and ConnectionFactory?
Spring JMS and WebSphere
Spring Support for JCA Message Endpoints
[1] For reference, here's our hard-won Camel config that connects Camel to a Message Queue via a JNDI resource (Connection Factory). Since we had to piece this config together with almost no documentation, I'm hoping a similar config can be done for Activation Spec.
<jee:jndi-lookup id="myTargetConnectionFactory" jndi-name="${mq.jndi-name}"/>
<bean id="jmsDestResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver"/>
<bean id="myConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="myTargetConnectionFactory"/>
<property name="username" value="${mq.username}"/>
<property name="password" value=""/>
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="myConnectionFactory" />
<property name="destinationResolver" ref="jmsDestResolver" />
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="10" />
<property name="cacheLevelName" value="CACHE_NONE" />
</bean>

Resources