IBM MQ Message Listener

Hi everyone knows how to create a message listener using IBM MQ? I know how to do this using the JMS specification, but I'm not sure how to do this for IBM MQ. Any links or pointers are welcome.

+4
source share
7 answers

Although there is a Java API Java WMQ, as previous respondents noted, WMQ supports JMS, so here are some resources to get you started there.

Take a look at this article: IBM WebSphere Developer Technical Journal: Launching a stand-alone Java application on WebSphere MQ V6.0

In addition, if you installed the full WMQ client and didn’t just capture the banks, you will have a lot of sample code. By default, they will work in C: \ Program Files \ IBM \ WebSphere MQ \ tools \ jms or / opt / mqm / samp depending on your platform.

If you need WMQ Client installation media, get here . Please note that this is a WMQ v7 client, not a v6 client. It is compatible with v6 QMgr, but since v6 is the end of life as of September 2011, you should do new development on the v7 client and, if possible, v7 QMgr. There are many functional and performance improvements if both sides are v7.

You can get the product guide here if you need it.

Finally, be sure when you get a JMS exception to print the associated exception. This is not a WMQ thing, but a JMS thing. Sun has provided a layered data structure for JMS exceptions, and the really interesting parts are often at a nested level. This does not really matter and can be implemented in several lines:

try { . . code that might throw a JMSException . } catch (JMSException je) { System.err.println("caught "+je); Exception e = je.getLinkedException(); if (e != null) { System.err.println("linked exception: "+e); } else { System.err.println("No linked exception found."); } } 

This helps determine the difference between a JMS error and a transport error. For example, a JMS security error may be WMQ 2035, or it may be a JSSE configuration, or the application may not have access to anything on the file system. Only one of them is worth spending a lot of time recoding WMQ error logs and only by printing the associated exception can you find out if it is one.

+6
source

Take a look at IBM Help: Writing basic WebSphere MQ Java applications

IBM has an API for interacting with queues. Here is their sample:

 import com.ibm.mq.*; // Include the WebSphere MQ classes for Java package public class MQSample { private String qManager = "your_Q_manager"; // define name of queue // manager to connect to. private MQQueueManager qMgr; // define a queue manager // object public static void main(String args[]) { new MQSample(); } public MQSample() { try { // Create a connection to the queue manager qMgr = new MQQueueManager(qManager); // Set up the options on the queue we wish to open... // Note. All WebSphere MQ Options are prefixed with MQC in Java. int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT ; // Now specify the queue that we wish to open, // and the open options... MQQueue system_default_local_queue = qMgr.accessQueue("SYSTEM.DEFAULT.LOCAL.QUEUE", openOptions); // Define a simple WebSphere MQ message, and write some text in UTF format.. MQMessage hello_world = new MQMessage(); hello_world.writeUTF("Hello World!"); // specify the message options... MQPutMessageOptions pmo = new MQPutMessageOptions(); // accept the // defaults, // same as MQPMO_DEFAULT // put the message on the queue system_default_local_queue.put(hello_world,pmo); // get the message back again... // First define a WebSphere MQ message buffer to receive the message into.. MQMessage retrievedMessage = new MQMessage(); retrievedMessage.messageId = hello_world.messageId; // Set the get message options... MQGetMessageOptions gmo = new MQGetMessageOptions(); // accept the defaults // same as MQGMO_DEFAULT // get the message off the queue... system_default_local_queue.get(retrievedMessage, gmo); // And prove we have the message by displaying the UTF message text String msgText = retrievedMessage.readUTF(); System.out.println("The message is: " + msgText); // Close the queue... system_default_local_queue.close(); // Disconnect from the queue manager qMgr.disconnect(); } // If an error has occurred in the above, try to identify what went wrong // Was it a WebSphere MQ error? catch (MQException ex) { System.out.println("A WebSphere MQ error occurred : Completion code " + ex.completionCode + " Reason code " + ex.reasonCode); } // Was it a Java buffer space error? catch (java.io.IOException ex) { System.out.println("An error occurred whilst writing to the message buffer: " + ex); } } } // end of sample 

I'm not sure if IBM banks are based on Maven repo. I know that in the past I had to extract them from a local IBM installation and put them in a local SVN repo. I use the following jars:

 <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mq</artifactId> <version>5.3.00</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mq.pcf</artifactId> <version>5.3.00</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mqbind</artifactId> <version>5.3.00</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mqjms</artifactId> <version>5.3.00</version> <scope>compile</scope> </dependency> 
+4
source

Take a look at the sample above.

In particular, on the lines

 MQGetMessageOptions gmo = new MQGetMessageOptions(); system_default_local_queue.get(retrievedMessage, gmo); 

You can configure get to wait for a specified time before throwing an MQRC_NO_MSG_AVAILABLE exception. Or you can wait forever.

 gmo.waitInterval= qTimeout; gmo.options = MQC.MQGMO_WAIT 

So, you can create a thread that continues to search for new messages and then passes them to the handler. Receiving and posting does not have to be in the same thread or even application.

Hope this helps answer your question.

+2
source

An important point in addition to the existing answers: JMS provides a MessageListener class that allows you to receive messages as asynchronous callbacks.

The native API does not have an equivalent function! You should re-call get(...) if necessary.

+2
source

in a loop before you receive a message that you can specify as shown below:

 gmo.options = MQC.MQGMO_WAIT gmo.waitInterval = MQConstants.MQWI_UNLIMITED; 

this causes the loop to wait until a message appears in the queue. For me it is like MessageListerner

+2
source

Just in case, someone will goover stackoverflow for the MQ Listener, as I did ... This may not be the answer due to the JMS implementation, but this is what I was looking for. Something like that:

 MQQueueConnectionFactory cf = new MQQueueConnectionFactory(); MQQueueConnection conn = (MQQueueConnection)cf.createQueueConnection(); MQQueueSession session = (MQQueueSession)conn.createSession(false, 1); Queue queue = session.createQueue("QUEUE"); MQQueueReceiver receiver = (MQQueueReceiver)session.createReceiver(queue); receiver.setMessageListener(new YourListener()); conn.start(); 

YourListener should implement the MessageListener interface, and you will receive messages in the onMessage (Message msg) method.

+2
source

Hello, here is a working example of a message listener with IBM MQ. Here I used spring also to create beans, etc.

 package queue.app; import javax.annotation.PostConstruct; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueReceiver; import javax.jms.QueueSession; import javax.jms.Session; import javax.jms.TextMessage; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.ibm.mq.jms.MQQueue; import com.ibm.mq.jms.MQQueueConnectionFactory; import com.ibm.msg.client.wmq.WMQConstants; @Component public class QueueConsumer implements MessageListener{ private Logger logger = Logger.getLogger(getClass()); MQQueueConnectionFactory qcf = new MQQueueConnectionFactory(); QueueConnection qc; Queue queue; QueueSession queueSession; QueueReceiver qr; @Value("${jms.hostName}") String jmsHost; @Value("${jms.port}") String jmsPort; @Value("${jms.queue.name}") String QUEUE_NAME; @Value("${jms.queueManager}") String jmsQueueMgr; @Value("${jms.username}") String jmsUserName; @Value("${jms.channel}") String jmsChannel; @PostConstruct public void init() throws Exception{ qcf.setHostName (jmsHost); qcf.setPort (Integer.parseInt(jmsPort)); qcf.setQueueManager (jmsQueueMgr); qcf.setChannel (jmsChannel); qcf.setTransportType (WMQConstants.WMQ_CM_CLIENT); qc = qcf.createQueueConnection (); queue = new MQQueue(QUEUE_NAME); qc.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); queueSession = qc.createQueueSession (false, Session.AUTO_ACKNOWLEDGE); qr = queueSession.createReceiver(queue); qr.setMessageListener(this); qc.start(); } @Override public void onMessage(Message message) { logger.info("Inside On Message..."); long t1 = System.currentTimeMillis(); logger.info("Message consumed at ...."+t1); try{ if(message instanceof TextMessage) { logger.info("String message recieved >> "+((TextMessage) message).getText()); } }catch(Exception e){ e.printStackTrace(); } } } 

Below are the dependencies that I have.

 <dependency> <groupId>com.sun.messaging.mq</groupId> <artifactId>fscontext</artifactId> <version>4.2</version> <scope>test</scope> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>jms</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>3.2.17.RELEASE</version> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mq</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mq.allclient</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mq.jmqi</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>com.ibm</groupId> <artifactId>com.ibm.mqjms</artifactId> <version>1.0</version> </dependency> 
0
source

All Articles