1
votes

I'm trying tho use simplified the JMS MQ connection from example JmsPutGet.java

    private static void testQueueManagerNew() throws JMSException {
        
                    JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
                    JmsConnectionFactory cf = ff.createConnectionFactory();

                    cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, "");
                    cf.setIntProperty(WMQConstants.WMQ_PORT, 1414);
                    cf.setStringProperty(WMQConstants.WMQ_CHANNEL, "MY_CNL");
//                  cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
                    
                    cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_BINDINGS);
                    cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, ""); //it should use default QM

                    JMSContext context = cf.createContext();
                    Destination destination = context.createQueue("queue:///" + "MY_QUEUE");

                    long uniqueNumber = System.currentTimeMillis() % 1000;
                    TextMessage message = context.createTextMessage("Your lucky number today is " + uniqueNumber);

                    JMSProducer producer = context.createProducer();
                    producer.send(destination, message);
                    LOGGER.info("Sent message:{}{}", message, System.lineSeparator());

                    JMSConsumer consumer = context.createConsumer(destination); // autoclosable
                    String receivedMessage = consumer.receiveBody(String.class, 15000); // in ms or 15 seconds
                    LOGGER.info("Rreceived message:{}{}", receivedMessage, System.lineSeparator());
    }

The changes I did are using the defaut Queue Manager (WMQConstants.WMQ_QUEUE_MANAGER is empty string), using the 'Binding' Connection Mode (WMQConstants.WMQ_CM_BINDINGS) and removing the host (WMQConstants.WMQ_HOST_NAME is empty string). I received following exception:

com.ibm.msg.client.jms.DetailedIllegalStateRuntimeException: JMSWMQ0018: Failed to connect to queue manager '' with connection mode 'Bindings' and host name '(1414)'.
    at com.ibm.msg.client.jms.DetailedIllegalStateException.getUnchecked(DetailedIllegalStateException.java:274)
    at com.ibm.msg.client.jms.internal.JmsErrorUtils.convertJMSException(JmsErrorUtils.java:173)
    at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createContext(JmsConnectionFactoryImpl.java:478)
    at poc.ibmmq.defaultqm.DefaultQM.testQueueManagerNew(DefaultQM.java:86)
    at poc.ibmmq.defaultqm.DefaultQM.main(DefaultQM.java:59)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2059' ('MQRC_Q_MGR_NOT_AVAILABLE').
    at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
    at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:418)
    at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:8475)
    at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7815)
    at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:303)
    at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createContext(JmsConnectionFactoryImpl.java:444)

It works with 'Client' Connection Mode when I specify host, but not with Binding. Also 'Binding' connection mode works when Queue Manager is specified (no default used). Is there necessary any extra Queue Manager setting?

1
Does your qm.ini have a default queue manger stanza?JoshMc
Yes, you are right. Only to complete, location is: \IBM\MQ\mqs.ini and section is: DefaultQueueManager: Name=...Marek-A-
yes, thank you, I typed that in a hurry from my phone, should have mentioned mqs.ini not qm.iniJoshMc

1 Answers

3
votes

In order to connect to a queue manager with 'Binding' connection mode, the queue manager must be on the same machine (same O/S image) as the application. 'Binding' connection mode uses inter-process - aka shared memory - to make the connection.

When making a connection using 'Client' connection mode, the application connects to the queue manager using a TCP/IP socket, with a connection made to the host and port number provided.

When making a connection using 'Client' connection mode, it is not necessary to provide a queue manager name on the connection call if you are happy to connect to whichever queue manager appears at the other end of the TCP/IP socket.

When making a connection using 'Binding' connection mode, the queue manager name is used to determine which local process to make the inter-process request to. You can only omit this name if you have nominated one of your locally hosted queue managers to be the default queue manager on this machine. It is not good enough to only have one queue manager, you must still nominate it to be the default.

In order to see whether you have any queue manager marked as the default on your machine, issue the following command:

dspmq -o default

If you have not got a default queue manager, you can make one of your locally hosted queue managers into the default one by following the instructions here.