简体   繁体   中英

IBM MQ listener using JMS in a JVM cluster

I have setup a JMS listener for IBM MQ . When the listener is running on single JVM like tomcat on local machine it runs fine. But when i deploy it to the Cloud where there are 2 VM's , it's running fine on one of the VM and connects to MQ but it says below on the other one.

Is there any limitation from IBM MQ on using a ID,password from multiple clients in order to connect to the Queue manager?

RROR> com.ssc.ach.mq.JMSMQReceiver[main]: errorMQJMS2013: invalid security authentication supplied for MQQueueManager
javax.jms.JMSSecurityException: MQJMS2013: invalid security authentication supplied for MQQueueManager
    at com.ibm.mq.jms.MQConnection.createQM(MQConnection.java:2050)
    at com.ibm.mq.jms.MQConnection.createQMNonXA(MQConnection.java:1532)
    at com.ibm.mq.jms.MQQueueConnection.<init>(MQQueueConnection.java:150)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:185)
    at com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:1066)
    at

I am starting the listener on VM startup using Servlet init method

    public void init(ServletConfig config) throws ServletException {
        logger.info("App Init");
        try {
            boolean isListnerOn = Boolean.parseBoolean(System.getProperty("listner", "false"));
            logger.info(" startReceiver , listner flag is "+isListnerOn);
            if(isListnerOn){
                if (mqReceive == null) {
                    MyMessageListener jmsListner = new MyMessageListener();
                    mqReceive = new JMSMQReceiver(jmsListner);
                }
                if (mqReceive != null) {
                    try{
                        mqReceive.start();
                    } catch (Exception e) {
                        logger.error("Error starting the listner ", e);
                    }

                }
            }else{
                logger.info(" listner not started as flag is "+isListnerOn);
            }

        } catch (Exception e) {
            logger.error(e, e);
        }
    }


private MQQueueConnectionFactory mqQueueConnectionFactory;



    public MQReceiver(MyMessageListener listner) {
        userName=System.getProperty( "mqId","");
        pwd=System.getProperty("mqId","");
        host = System.getProperty(PREFIX + ".host");
        port = Integer.parseInt(System.getProperty(PREFIX + ".port"));
        qManager = System.getProperty(PREFIX + ".qManager");
        channel = System.getProperty(PREFIX + ".channel");
        queueName = System.getProperty(PREFIX + ".achqueueName");
        logger.info("HOST:" + host + "\tPORT:" + port + "\tqManager:"+ qManager + "\tchannel:" + channel + "\tqueueName:"+ queueName);
         try {

         mqQueueConnectionFactory = new MQQueueConnectionFactory();
         mqQueueConnectionFactory.setHostName(host);
         mqQueueConnectionFactory.setChannel(channel);//communications link
         mqQueueConnectionFactory.setPort(port);
         mqQueueConnectionFactory.setQueueManager(qManager);//service provider 
         mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
         queueConnection = mqQueueConnectionFactory.createConnection(trustUserName, trustID);
         session = queueConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
         queue = session.createQueue(queueName);  
         ((MQDestination) queue).setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);
         MessageConsumer consumer = session.createConsumer(queue);
          consumer.setMessageListener(listner);
        logger.info(" Connect MQ successfully.");

         } catch (JMSException e) {
              logger.error("error" + e.getMessage(), e);
            }
    }

    public void start() {
        logger.info("Starting MQListener... ");
        //mqListener.start();
         try {
            queueConnection.start();
            logger.info("MQListener start successfully");
        } catch (JMSException e) {
               logger.error("error" + e.getMessage(), e);
        }

    }
com.ssc.ach.mq.JMSMQReceiver[main]: errorMQJMS2013: invalid security authentication supplied for MQQueueManager
javax.jms.JMSSecurityException: MQJMS2013: invalid security authentication supplied for MQQueueManager

Is because:

queueConnection = mqQueueConnectionFactory.createConnection(trustUserName, trustID);

If you don't supply a valid UserId and Password that can be authenticated by the queue manager then your connection will rejected. I have no idea what you are passing into the method but it is supposed to be a valid UserId and Password for the remote system.

Also, I wish people would stop using the term 'MQ Listener' because you are not creating an 'MQ Listener', you are creating a consumer that is receiving messages.

An MQ listener is a component of MQ that accepts and handles incoming connections. See here .

The IBM MQ Classes for JMS client error JMSWMQ2013 can be caused by quite a few issues.

IBM Support Technote " WMQ 7.1 / 7.5 / 8.0 / 9.0 queue manager RC 2035 MQRC_NOT_AUTHORIZED or AMQ4036 or JMSWMQ2013 when using client connection as an MQ Administrator " has a good write up on diagnosing and resolving issues like this.

If you want more specific help, to start with please provide the following details by editing and adding them to your question.

  1. Version of IBM MQ Classes for JMS used by the client application.
  2. Version of IBM MQ installed on the IBM MQ queue manager
  3. Errors in the queue manager's AMQERR01.LOG that happen at the same time as the error you receive in the IBM MQ Classes for JMS client application on the second VM..

It is strange that it works on the first VM and fails on the second. If the trustUserName, trustID are the same for both VMs, IBM MQ should accept them equally.

If you are using IBM MQ v8 or later native connection authentication it is possible the OS or PAM is denying the second connection. I have only seen this where pam_tally had a limit of 5 and more than 5 connection hit at the same time. It could be possible there is some sort of login limit of one login per user.


Per you comment it appears that you had a CHLAUTH ADDRESSMAP rule missing, the first VM's IP was allowed and the second VM's IP was not allowed. Depending on how the queue manager is configured and how the CHLAUTH rule is blocking the connection the queue manager may return MQRC 2035 to the client. On a IBM MQ Classes for JMS client this is returned as MQJMS2013. This could happen for instance if your queue manager is using ADOPTCTX(NO) and has a CHLAUTH rule that maps ADDRESS(*) to a MCAUSER that does not exist (ex: *NOACCESS ) and other CHLAUTH rules that map connections from specific IPs to a user that does have access.

A more secure setup is to use ADOPTCTX(YES) which will tell MQ to set the MCAUSER to the id that is authenticated by CONNAUTH. You could also have a ADDRESSMAP rule with ADDRESS(*) USERSRC(NOACCESS) to block by default and then other rules with specific IPs and USERSRC(CHANNEL to allow those IPs you want to whitelist.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM