Spring + JMS + ActiveMQ without dependency on ActiveMQ - spring

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.

Related

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?

Which HornetQ libraries i need for JMS client?

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.

Do I have to use jetty embeded server to test my active mq structure in a Spring project?

Do I have to use jetty embeded server to test my active mq structure in a Spring project? Any help would be appreciated.
Please see the following links from ActiveMQ:
How to unit test JMS code
Integration Tests > Example Testing Scenario
Unit testing with JMS (ActiveMQ)
At first, add context your listener container bean like the following:
<bean id="sampleListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="concurrency" value="20-100"/>
<property name="connectionFactory" ref="connectionFactory"/>
<property name="destination" ref="sampleDestination"/>
<property name="messageListener" ref="sampleListenerConsumer"/>
</bean>
Secondly,
DefaultMessageListenerContainer container = BeanProvider.getBeanFactory().getBean("sampleListenerContainer", DefaultMessageListenerContainer.class);
container.start();
Similarly,
container.stop();

Nested Spring TxProxyTemplate issue

I have the following config.
<bean id="abcManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.AbcManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="xyzManager" ref="xyzManager"/>
</bean>
</property>
</bean>
<bean id="xyzManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.XyzManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="anotherManager" ref="anotherManager"/>
</bean>
</property>
</bean>
<bean id="anotherManager" parent="TxProxyTemplate">
<property name="target">
<bean class="com.x.y.AnotherManagerImpl">
<property name="abcDAO" ref="abcDAO"/>
<property name="oneMoreManager" ref="oneMoreManager"/>
</bean>
</property>
</bean>
What is the issue with the following configuration? will having the same DAO at the different levels cause concurency issues?
We found that we get lots of weblogic connection releases when we have high load.
How is this related to the connection release issue?
We use Hibernate for DAO operations.
First, analyse the logs to see when spring creates and closes transactions.
Set the logger for org.springframework.transaction to DEBUG for this.
Next my guess is you need to examine your #Transactional annotations (which I assume you use on your managers (=services?). Make sure the propagation is set correctly because this might be related to your issue (hard to say without seeing your manager's code of course).
To answer your question directly:
What is the issue with the following configuration? will having the same DAO at the different levels cause concurency issues?
Nothing, and no. I don't see anything wrong with this. Not sure what you mean about 'same DAO' - you don't have the same DAO. You have the same parent, but 3 distinct DAOs.
If you're asking, then, why is weblogic closing your DB connections before your transaction completes, we wouldn't be able to answer that with the information above.

Spring IntTest is getting "Failed to grow the connection pool" from Atomikos

I have a Spring application that normally runs fine in WebLogic.
I have a set of integration tests that use the Atomikos "Transaction Essentials" framework to provide the standalone transaction manager. I had this working, but I'm now seeing a new problem, but I don't know what I might have changed that would make this happen.
I'm seeing a stack trace beginning like this:
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.atomikos.jdbc.AtomikosSQLException: Failed to grow the connection pool
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
Here are the relevant bean definitions:
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<!-- when close is called, should we force transactions to terminate or not? -->
<property name="forceShutdown">
<value>true</value>
</property>
</bean>
<!-- Also use Atomikos UserTransactionImp, needed to configure Spring -->
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout">
<value>300</value>
</property>
</bean>
<!-- Configure the Spring framework to use JTA transactions from Atomikos -->
<bean id="catalogTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager">
<ref bean="atomikosTransactionManager" />
</property>
<property name="userTransaction">
<ref bean="atomikosUserTransaction" />
</property>
</bean>
I also have several like this:
<bean id="appConfigDataSource"
class="com.atomikos.jdbc.AtomikosDataSourceBean"
p:uniqueResourceName="appConfigDataSource"
p:xaDataSourceClassName="oracle.jdbc.xa.client.OracleXADataSource"
p:poolSize="5">
<property name="xaProperties">
<props>
<prop key="user">${ds.appconfig.userName}</prop>
<prop key="password">${ds.appconfig.password}</prop>
<prop key="URL">${ds.appconfig.url}</prop>
</props>
</property>
</bean>
I tried changing the "5" to "50". This makes it run longer, but it still fails with the same error. There's no way that it would even need 5 or even 50 connections. I have a strong feeling that if I changed it to a larger number, it would run even longer, and still fail with the same error.
What might I be missing?
Never mind. It was a simple problem. I forgot that the hostname of my test database changed a while ago, and I forgot to change the property value.

Resources