ibm-messaging / mq-jms-spring

Components to assist MQ JMS integration with Spring frameworks
Apache License 2.0
190 stars 102 forks source link

MQ Queue Manager Channel Name is disappearing form the JmsConnectionFactory when we use them across both JmsListener and JmsTemplate #70

Open litheshgopal opened 3 years ago

litheshgopal commented 3 years ago

**MQ Queue Manager Channel Name is disappearing form the JmsConnectionFactory when we use them across both JmsListener and JmsTemplate

Spring JMS - mq-jms-spring-boot-starter (Version 2.0.0) java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory(); mqQueueConnectionFactory.setHostName(lsHost); mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT); mqQueueConnectionFactory.setChannel(lsChannel); mqQueueConnectionFactory.setPort(loPort); mqQueueConnectionFactory.setQueueManager(lsManager); mqQueueConnectionFactory.setPollingInterval(loPollingInterval); mqQueueConnectionFactory.setSSLSocketFactory(loSSLSocketFactory); mqQueueConnectionFactory.setSSLFipsRequired(false); mqQueueConnectionFactory.setSSLCipherSuite(lsSslCipherSuite); mqQueueConnectionFactory.setSSLPeerName(lsSslPeerName);

CachingConnectionFactory loCacheConnFactory = new CachingConnectionFactory(); loCacheConnFactory.setTargetConnectionFactory(mqQueueConnectionFactory); loCacheConnFactory.setSessionCacheSize(loCacheSize); loCacheConnFactory.setCacheConsumers(true); loCacheConnFactory.setReconnectOnException(true);

JmsTransactionManager loJmsTransactionManager = new JmsTransactionManager(loCachingConnectionFactory);

JmsTemplate loJmsTemplate = new JmsTemplate(loCachingConnectionFactory); loJmsTemplate.setPubSubDomain(false); loJmsTemplate.setDeliveryPersistent(true); loJmsTemplate.setReceiveTimeout(loTimeOut); loJmsTemplate.setSessionTransacted(true);

DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(aCachingConnectionFactory); factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER); factory.setConcurrency("1-5"); factory.setSessionTransacted(lbSessionTranscated); factory.setAutoStartup(true); factory.setReceiveTimeout(loTimeOut); factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER); factory.setTransactionManager(loJmsTransactionManager);

SimpleJmsListenerEndpoint loEndPoint = new SimpleJmsListenerEndpoint(); loEndPoint.setMessageListener(loMessageListenerInstance); loEndPoint.setDestination(lsQueueName);

DefaultMessageListenerContainer loListenerContainer = factory. createListenerContainer(loEndPoint);

loListenerContainer.setMaxConcurrentConsumers(loMaxConcurrentConsumer); loListenerContainer.setConcurrentConsumers(loConcurrentConsumer); loListenerContainer.setIdleTaskExecutionLimit(loIdleTaskExeLimit); loListenerContainer.setMaxMessagesPerTask(loMaxMsgPerTask); loListenerContainer.setIdleConsumerLimit(loIdleConsumerLimit); loListenerContainer.setAcceptMessagesWhileStopping(false);

loJmsTemplate.send(aQueueName, MessageCreator);

2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] org.springframework.transaction.CannotCreateTransactionException: Could not create JMS transaction; nested exception is com.ibm.msg.client.jms.DetailedJMSException: JMSWMQ0018: Failed to connect to queue manager '' with connection mode 'Client' and host name 'RBSMQ-RS861AC.server.rbsgrp.net(5111)'. 2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information. 2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] at org.springframework.jms.connection.JmsTransactionManager.doBegin(JmsTransactionManager.java:234) 2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:378) 2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] at com.rbs.bdd.mq.clustered.framework.message.sender.impl.ClusteredMessageSenderImpl.sendMessageToQueue(ClusteredMessageSenderImpl.java:128) 2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] at com.rbs.bdd.mq.clustered.framework.message.sender.impl.ClusteredMessageSenderImpl.sendMessage(ClusteredMessageSenderImpl.java:73) 2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] at com.rbs.bdd.mq.clustered.framework.message.sender.impl.ClusteredVanquishTextMessageSenderImpl.dispatchMessage(ClusteredVanquishTextMessageSenderImpl.java:42) 2021-06-10T12:32:06.016+01:00 [APP/PROC/WEB/0] [ERR] at com.rbs.bdd.api.service.InwardRetrieveServiceImpl.sendMessageToClusteredQueue(InwardRetrieveServiceImpl.java:97) 2021-06-10T12:32:06.017+01:00 [APP/PROC/WEB/0] [ERR] at com.rbs.bdd.api.service.InwardRetrieveServiceImpl.processRetrieveRequest(InwardRetrieveServiceImpl.java:80) 2021-06-10T12:32:06.017+01:00 [APP/PROC/WEB/0] [ERR] at com.rbs.bdd.api.controller.InwardPaymentController.processRetrieveRequest(InwardPaymentController.java:53) 2021-06-10T12:32:06.017+01:00 [APP/PROC/WEB/0] [ERR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 2021-06-10T12:32:06.017+01:00 [APP/PROC/WEB/0] [ERR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 2021-06-10T12:32:06.017+01:00 [APP/PROC/WEB/0] [ERR] at

When we explicitly set mqQueueConnectionFactory.setChannel(lsChannel); before loJmsTemplate.send(aQueueName, MessageCreator); thing are working as expected! Not sure why channel is Vanished from the pre-configured ConnectionFactory object?**

ibmmqmet commented 3 years ago

I've got no real idea what's going on here. Your code doesn't compile (even when obvious variables like the qmgr and channel names are added) so it's rather difficult to know what you are trying to do. But I suspect that you are trying and not quite succeeding in bypassing the automatic connection configuration done by Spring Boot that sets defaults on connections when the CFs are created.

Though you also say you are using v2.0.0 of the starter which is 3 years old, and all kinds of things have changed since then.

chughts commented 3 years ago

I doubt very much that this is one long continuous method, but this is how you have written it. It makes it very hard to debug your code, as it appears that (even though you are on a back level version of the MQ Spring boot starter) your issue is in how you are making use of connection factory beans.

Let me explain why its difficult to debug your code -

You initialise a CachingConnectionFactory as loCacheConnFactory, which you don't subsequently use.

You base your JmsTemplate on loCachingConnectionFactory, which is never initialised.

JmsTemplate loJmsTemplate = new JmsTemplate(loCachingConnectionFactory);

and you base your JmsListenerContainerFactory on aCachingConnectionFactory, which is nowhere else in your code.

DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(aCachingConnectionFactory);

I would expect you to be using syntax similar to the configurations, components and beans defined in this sample - https://github.com/ibm-messaging/mq-dev-patterns/tree/master/Spring-JMS/src/main/java/com/ibm/mq/samples/jms/spring/level114

litheshgopal commented 3 years ago

I've got no real idea what's going on here. Your code doesn't compile (even when obvious variables like the qmgr and channel names are added) so it's rather difficult to know what you are trying to do. But I suspect that you are trying and not quite succeeding in bypassing the automatic connection configuration done by Spring Boot that sets defaults on connections when the CFs are created.

Though you also say you are using v2.0.0 of the starter which is 3 years old, and all kinds of things have changed since then.

Hello Mark,

Many thanks for your review and suggestions, I haven't pasted the full code in my previous post because I thought just a sample template would suffice. I have attached my full code here and it will help you to understand what we are trying to implement. I have upgraded the version to latest (2.4.2) as well. Please let me know if you have any further queries on this. I am using multiple Queue Managers (load balanced QM's) and the code is dynamically creating the CF's and get assigned to JmsListeners and JmsTemplate.

Regards, Lithesh

package com.rbs.bdd.mq.clustered.framework.config;

import java.io.InputStream; import java.security.KeyStore; import java.security.Provider; import java.security.Security; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.Properties; import java.util.StringTokenizer;

import javax.jms.JMSException; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory;

import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Scope; import org.springframework.core.io.ClassPathResource; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.SimpleJmsListenerEndpoint; import org.springframework.jms.connection.CachingConnectionFactory; import org.springframework.jms.connection.JmsTransactionManager; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.listener.DefaultMessageListenerContainer; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; import org.springframework.transaction.PlatformTransactionManager;

import com.ibm.mq.jms.MQQueueConnectionFactory; import com.ibm.msg.client.wmq.WMQConstants; import com.rbs.bdd.crypto.service.DecryptionService; import com.rbs.bdd.mq.clustered.framework.common.exception.VanquishRuntimeException; import com.rbs.bdd.mq.clustered.framework.error.handler.ClusteredErrorHandler; import com.rbs.bdd.mq.clustered.framework.exception.handler.ClusteredExceptionListener; import com.rbs.bdd.mq.clustered.framework.listener.ClusteredMessageListener; import com.rbs.bdd.mq.clustered.framework.listener.impl.ClusteredBDDMessageListenerImpl; import com.rbs.bdd.mq.clustered.framework.model.ClusteredListenerContainerModel; import com.rbs.bdd.mq.clustered.framework.model.ClusteredListenerContainers; import com.rbs.bdd.mq.clustered.framework.model.JmsTemplateModel; import com.rbs.bdd.mq.clustered.framework.model.impl.ClusteredListenerContainersImpl; import com.rbs.bdd.mq.clustered.framework.props.BDDClusteredMQMessageProperties; import com.rbs.bdd.mq.clustered.framework.props.ClusteredJmsProperties; /** --------------------------------------------------------------------------------------------------------

}