Combining WebSphere MQ connections with Tomcat

Tomcat has a built-in JDBC connection pool, but unfortunately there is no built-in JMS connection pool.

We are migrating an outdated Tomcat web application from WebSphere MQ version 6-7. Unfortunately, the connection pool has been deleted in WebSphere MQ 7, as described here: http://www-01.ibm.com/support/docview.wss?uid=swg21665128

Now we are afraid that we will have problems if we simply use the following code to configure MQ in Tomcat:

<Resource name="jms/XXXQCF" auth="Container" type="com.ibm.mq.jms.MQQueueConnectionFactory" factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory" description="JMS Queue Connection Factory" HOST="xxx.com" PORT="1429" CHAN="XXX" TRAN="1" QMGR="XXX" /> 

The reason for our concern is that when using MQ 7 it will not use a unified JMS provider. See http://activemq.apache.org/jmstemplate-gotchas.html for more details.

Alternative solutions we see:

1) Using Atomikos

Atomikos has com.atomikos.jms.AtomikosConnectionFactoryBean, which can be used instead of MQQueueConnectionFactory But using the XA transaction manager is a huge overhead when we don't need XA

2) Use Spring CachingConnectionFactory

Looks like a good solution, but unfortunately our legacy application does not use Spring. Therefore, we assume that using a CachingConnectionFactory will mean very little effort.

3) Using Apache Commons Pool

looks promising, but for its proper implementation for JMS some good JMS knowledge is required

Our questions:

  • Is there a JMS provider that can be used to migrate the MQQueueConnectionFactory and which will combine connections, sessions, manufacturers and consumers?
  • Has anyone succeeded in implementing one of the alternative solutions described above?
+2
source share
2 answers

As suggested by Umapathy in option 3, we have now chosen the approach using Spring CachingConnectionFactory, and it works well even for a Spring application. All you have to do is add Spring banners to the classpath and wrap the MQQueueConnectionFactory with a CachingConnectionFactory.

We decided to create our own Tomcat QueueConnectionFactoryFactory, which allows us to completely abandon the source code of the application, you just need to replace the original MQ factory connection from the Tomcat configuration file (see above in the question) with the following XML definition:

 <Resource name="jms/XXXQCF" auth="Container" type="org.springframework.jms.connection.CachingConnectionFactory" factory="at.rsf4j.core.utilities.RSFCachingMQQueueConnectionFactoryFactory" description="JMS Queue Connection Factory" HOST="xxx.com" PORT="1429" CHAN="XXX" TRAN="1" QMGR="XXX" /> 

Here is the (simplified) code (without error checking) for RSFCachingMQQueueConnectionFactoryFactory:

 public class RSFCachingMQQueueConnectionFactoryFactory implements ObjectFactory{ public Object getObjectInstance (Object obj, Name name, Context nameCtx, Hashtable<?,?> environment) throws NamingException { Reference ref = (Reference) obj; String beanClassName = ref.getClassName(); Class<?> beanClass = Class.forName(beanClassName); if (CachingConnectionFactory.class.isAssignableFrom(beanClass)){ MQQueueConnectionFactoryFactory cff = new MQQueueConnectionFactoryFactory(); Reference mqReference = new Reference( MQQueueConnectionFactory.class.getName()); Enumeration<RefAddr> allAddrs = ref.getAll(); while (allAddrs.hasMoreElements()){ mqReference.add(allAddrs.nextElement()); } MQQueueConnectionFactory cf = (MQQueueConnectionFactory)cff.getObjectInstance(mqReference, name, nameCtx, environment); CachingConnectionFactory ccf = (CachingConnectionFactory)beanClass.newInstance(); ccf.setTargetConnectionFactory(cf); return ccf; } } 
+2
source

I think you already know the answer.

Option 1: Migrating from the Java EE Application Server It has built-in JMS pools.

option 2: If this is a simple application that performs one task (for example, placing in a queue with fire and type of forgetting), you can connect to the JMS provider (qmgr) and create a producer or user in the servlet_init method, which means that outdated code needs in the update. You also need to take care of reconnecting when something breaks, as the JMS reconnect properties will not start reconnecting (as far as I know).

option 3: I started with Spring CachingConnectionFactory when the application turned out to be more complex than the one in option 2. I have applications that use JMSTemplate, and some do not.

+1
source

Source: https://habr.com/ru/post/1391786/


All Articles