Reputation: 852
I have a spring boot application which uses JMS template to communicate with queue services.
Here is my producer definition:
<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory">
<bean class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="targetConnectionFactory">
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType" value="1"/>
<property name="queueManager" value="${queueManager}"/>
<property name="hostName" value="${connName}"/>
<property name="port" value="${connPort}" />
<property name="channel" value="${channel}"/>
</bean>
</property>
</bean>
</property>
<property name="sessionCacheSize" value="10"/>
<property name="cacheConsumers" value="false"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.integration.jms.DynamicJmsTemplate">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.MappingJackson2MessageConverter"></bean>
</property>
</bean>
<!-- JMS outbound gateway -->
<int-jms:outbound-gateway
id="myJmsOutboundGateway"
connection-factory="jmsConnectionFactory"
request-destination-expression="headers.request_destination_queue"
request-channel="jmsOutboundRequestChannel"
reply-destination-expression="headers.reply_destination_queue"
reply-channel="jmsOutboundReplyChannel"
explicit-qos-enabled="true"/>
Here is consumer definition which stays in other project to listen queue:
<!-- Transation flow start -->
<bean id="inboundQueue" class="com.ibm.mq.jms.MQQueue">
<constructor-arg index="0" value="${queueManager}"/>
<constructor-arg index="1" value="#{'inQueue'}"/>
<property name="targetClient" value="1" />
</bean>
<int:channel id="jmsOutboundChannel" />
<int-jms:outbound-channel-adapter
id="acquirerOutboundAdapter"
destination-name="destinationQueue"
jms-template="jmsTemplate"
channel="jmsOutboundChannel"/>
When I run the project and try to send message over IBM MQ, I get this exception:
JMS attempted to perform an MQPUT or MQPUT1; however IBM MQ reported an error.
Use the linked exception to determine the cause of this error.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2027' ('MQRC_MISSING_REPLY_TO_Q').
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:274)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:185)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:507)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:584)
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:691)
at
When we checked headers in message in debug mode, we saw that header which told as missing stays in message headers:
jms_destination=queue:///destinationQueue
jms_timestamp=1650004155460
JMS_IBM_PutApplType=28
JMS_IBM_Format=
id=3d22ed9e-d665-8c9a-7995-bb1a2b0c36eb
acquirerId=404045
jms_messageId=ID:414d5120514d3120202020202020202079ca536203fb1940
JMS_IBM_MsgType=1
JMSXUserID=mqm
priority=4
acq_rsp_ts=1650004162979
ReplyToQ=destinationQueue
JMS_IBM_Character_Set=UTF-8
JMS_IBM_Encoding=273
reply_destination_queue=destionationQueue
jms_replyTo=queue://QM1/destionationQueue
startTime=1650004162965
JMS_IBM_PutTime=06291556
request_destination_queue=inQueue
JMSXAppID=core.SoftPOSApplication
jms_redelivered=false
JMS_IBM_PutDate=20220415
jms_correlationId=210595709001
ReplyToQMgr=destinationQueue
Why are we facing this problem although header stays in headers? How can we solve this problem?
Upvotes: 0
Views: 1472
Reputation: 1
If the message type has been set to one of "Request", MQ will check for the presence of a reply to queue in the MQ header; obviously you would want the reply to queue to be present on the queue manager but I don't believe the reply to queue actually has to exist at the time the application puts the message for the put to succeed. Here is a snippet of JMS code that would demonstrate that:
Destination sendTo = session.createQueue("IN.Q");
Destination replyTo = session.createQueue("IN.Q.REPLY");
MessageProducer producer = session.createProducer(sendTo);
Message msg = session.createTextMessage("test");
msg.setIntProperty("JMS_IBM_MsgType",com.ibm.mq.constants.MQConstants.MQMT_REQUEST);
// Uncomment the line below to prevent a '2027' ('MQRC_MISSING_REPLY_TO_Q') error
// msg.setJMSReplyTo(replyTo);
producer.send(msg);
I appreciate this isn't a complete answer but hopefully it will help you understand what is happening and focus on debugging the Spring configuration.
Upvotes: 0