MQRC_UNKNOWN_ALIAS_BASE_Q when using spring JmsTemplate to send message

3k Views Asked by At

When I try to send the JMS message to the external queue It is failing with below error

error occured while sending the message :JMSWMQ2008: Failed to open MQ queue 'TESTQUEUE'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2082' ('MQRC_UNKNOWN_ALIAS_BASE_Q').

Jms Template declaration

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="cachedJmsQueueConnectionFactory" />
        <property name="pubSubDomain" value="false" />
        <property name="receiveTimeout" value="2000" />
    </bean>

<bean id="testQueue" class="com.ibm.mq.jms.MQQueue">
        <property name="baseQueueManagerName" value="${test.qmgrName}" />
        <property name="baseQueueName" value="${test.queue}" />
    </bean>

this.jmsTemplate.convertAndSend(getDestinationBean("testQueue"),
                        message.getJson());

but if I use dynamic destination resolver with jmsTemplate, I could send the message

this.jmsTemplate.convertAndSend("TESTQUEUE", message.getJson());

2

There are 2 best solutions below

0
On

In this situation when one program works and one does not the difference is that the two programs have resolved to different queue names. To figure out what's wrong requires understanding of how the names are resolved. There are two possibilities for which 2082: MQRC_UNKNOWN_ALIAS_BASE_Q results:

  1. The alias queue's TARGQ attribute points to a non-existent queue.
  2. The alias queue refers to a non-local clustered queue.

In the first case an alias queue is defined over a local queue but the definition is defective in some way. Often it is because the local queue name is misspelled. The result is that TARGQ has nothing local to which it can resolve. This is easy enough to diagnose by simple inspection or by using amqsput or any other sample which puts a message onto the queue.

The only way this can work in one instance and not the other as described is that one app resolves to the alias queue and one does not. For instance, one of the two apps specifies a non-local QMgr name and the message is put directly to a transmission queue whereas the other one hits a dead-end by resolving to the broken alias.

The second case is when the alias resolves to a non-local clustered queue but the calling program has specified the local QMgr name as part of the destination. The key to understanding this case is that, unlike a QRemote which can re-map the QMgr name, a QAlias does not change the QMgr name specified by the calling app. Since the QMgr name should not be provided to resove a clustered queue, supplying a non-blank string here breaks resolution.

Here's why...When opening a clustered queue an app specifies no QMgr name and MQ decides which instance to send to. The name resolution mechanism looks locally first and if it finds a clustered queue it uses the CLWLUSEQ attribute to decide whether to prefer the local instance over clustered instances. But if what it finds is an alias over a clustered queue it re-drives resolution using the TARGQ name. If the local QMgr name has been specified as part of a fully-qualified destination address and there is no local queue instance that matches TARGQ, there is no way to resolve it at that point and resolution fails. To successfully use an alias over a clustered queue therefore requires the calling program to not specify a QMgr name.

So both programs are resolving to different queue names. That you believe they are resolving to the same name when the behavior indicates they cannot possibly be needs to be dealt with to diagnose this further.

The best thing to do is to use a known-good piece of code for which resolution is unambiguous. The amqsput sample is good but what you really need to test this is a program that allows you to specify both the QMgr name to connect to and the QMgr name for the destination address, such as the Q program from SupportPac MA01. Recreate the error by variously specifying the local QMgr name in the destination or leaving it blank and you will be able to discern the case in which it fails and then modify the code accordingly.

0
On

As mentioned by Rob if it is a clustered queue then don't specify the queue manager.

<bean id="testInQueue" class="com.ibm.mq.jms.MQQueue">
   <property name="baseQueueName" value="${test.queue}" />
</bean>

This config worked for me.