JMS - Java Message Service



Native MQ J2EE interface access to IBM Websphere MQ version 5.2.1 / 5.3 / 6.0 (MQseries)

In the following we will deal with: Standard JMS J2EE interface provide possibility for following message types to be used: Please notice that the com.ibm.jms.JMS* classes is a complete new inheritance hierachy rather than just a blind wrapper of the javax.jms.* message types. MQ really understands both - since i this example we can create a regular javax.jms.TextMessage and sublit it to MQ through the native interface - but in fact it comes out as a com.ibm.jms.JMSTextException when returned from MQ.

In the following, we will mainly consider JMSTextMessage and JMSBytesMessage.

In this simple example, it makes no practical difference using thecom.ibm.jms.JMS* classes rather than javax.jms.* message types. But important is the additional possiblity to set a wide range of transfer parameters on the com.ibm.mq.jms.MQQueue class rather on the sipmle javax.jms.Queue class.

For all MQ versions, the following basic set of jar-files are used for non-transactional communication from J2EE client directly to MQ :



MQ v5.2.1 MA88

25-07-2002 09:39 249.780 com.ibm.mq.jar
25-07-2002 09:39 39.267 com.ibm.mqbind.jar
25-07-2002 09:39 1.339.712 com.ibm.mqjms.jar
28-01-2002 09:29 17.978 connector.jar
28-01-2002 09:30 22.769 fscontext.jar
28-01-2002 09:30 77.116 providerutil.jar

MQ v5.3 CSD 11 (you need a login to access files)

01-03-2003 00:00 3.000 com.ibm.mqetclient.jar (required only if you want to interact transactionally)
02-08-2005 01:00 344.964 com.ibm.mq.jar
02-08-2005 01:00 41.816 com.ibm.mqbind.jar
02-08-2005 01:00 1.785.421 com.ibm.mqjms.jar
02-08-2005 01:00 17.978 connector.jar
02-08-2005 01:00 22.769 fscontext.jar
02-08-2005 01:00 77.116 providerutil.jar

MQ v6.0 (out-of-the box)

24-05-2005 01:00 3.363 com.ibm.mqetclient.jar (required only if you want to interact transactionally)
24-05-2005 02:00 421.771 com.ibm.mq.jar
24-05-2005 02:00 1.230.751 com.ibm.mqjms.jar
24-05-2005 02:00 2.099.749 dhbcore.jar
24-05-2005 02:00 22.769 fscontext.jar
24-05-2005 02:00 77.116 providerutil.jar
I have to be honest and admit I worked with MQ 5.2.1 - but haven't tried a J2EE client towards MQ 5.2.1 - I only dissassembled some of the code to look if it worked in the same way as 5.3 - and that seemed to be the case.

Specific for the MQ versions :

MQ 5.2.1 has been out of support since 2003-12-31 and will require installation of a fixpack
"MA88" to support Java at all. It's going to be hard to get, because most IBM download locations have taken them off-line (except the link provided here - where you don't even have to do a logon). Then, however, a J2EE client will connect to MQ using the usual set of J2EE client jar-files mentioned above. I honestly haven't tried J2EE clients from machines without the MQ installation - but odds are, it should work.

MQ 5.3 really comes with J2EE support "out-of-the-box". But if you want to connect transactional, you need to seek out a special IBM update "MQt5302w/C48UVML" sized 4.825.675 bytes for the "MQ Extended Transactional Client Installation" to get the com.ibm.mqetclient.jar for MQ 5.3. Oddly enough, it's not included in any of the normal CSD's up to level 11 (and probably beyond). Also, if you want to deal with publish/subscribe messaging, you need support pack "MA0C" - and then you need to setup a bunch of standard queues... From a J2EE connection point of view, MQ 5.3 is equally flexiable as 6.0 - doing both transactional/non-transactional connect from remote machines without a MQ installation (only with jar-files in active classloader).

MQ 6.0 seems like it provides the most basic stuff - and so far little extra setup is required. I'm gonna use it here for demostrations - even though I tried most things with MQ 5.3 as well.

Contained in this session:
J2EE client, external JNDI support, MQ setup

This example will create a client, using external file-based JNDI, sending messages to a MQ - which subsequely is caught by a Message Driven Bean (MDB) running from a Weblogic 8.1 installation.

Initially, we will run without a security manager and require that the MQ installation and the J2EE applications are running from the same machine. Later will introduce the security manager and perform authentication from another machine.

First, edit the JMSAdmin.config file under IBM\WebSphereMQ\Java\bin installation to set the external JNDI provider Context Factory:


setting up JMSAdmin configuration in the MQ installation
JMSAdmin.config

...
	INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
	#INITIAL_CONTEXT_FACTORY=com.sun.jndi.ldap.LdapCtxFactory
	#INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
	#INITIAL_CONTEXT_FACTORY=com.ibm.ejs.ns.jndi.CNInitialContextFactory
	#INITIAL_CONTEXT_FACTORY=com.ibm.websphere.naming.WsnInitialContextFactory
	#
	#  The following line specifies the URL of the service provider's initial
	#  context. It currently refers to an LDAP root context. Examples of a
	#  file system URL and WebSphere's JNDI namespace are also shown, commented
	#  out.
	#
	PROVIDER_URL=file:/C:/jms-jndi-directory
	#PROVIDER_URL=ldap://localhost:389/ou=Groups,o=Airius.com
	#PROVIDER_URL=ldap://polaris/o=ibm,c=us
	#PROVIDER_URL=file:/C:/JNDI-Directory
	#PROVIDER_URL=iiop://localhost/
...
	#
	#  The following line specifies the security authentication model in use,
	#  and may be 'none' (for anonymous authentication), 'simple', or 'CRAM_MD5'.
	#
	SECURITY_AUTHENTICATION=none
...

	#Leave out the following entries as they probably already are
	#PROVIDER_USERDN
	#PROVIDER_PASSWORD
...



Secondly, it's necessary to configure the Websphere MQ version 6.0 installation by defining the QUEUE manager... Calling it BEAMQ (after all, we're using it with BEA Weblogic server).

Start the MQ navigator and define the queue manager using standard settings...

Websphere MQ navigator definition of new queue manager

MQ navigator wizard for queue manager

Make sure you define a port not already used. Choosing port 1421 here - but that could practically be any other port not already used...

Websphere MQ setup of queue manager

Once the queue manager is in place, define the actual queue. Basicly, it means accepting all recommended standard settings.

Websphere MQ queue setup wizard

Websphere MQ local queue setup

Websphere MQ local queue setup

Websphere MQ local queue setup

Set up the external JNDI provider through JMSAdmin - with definitions matching the queue manager and queue, defined above.


setting up external JNDI through JMSAdmin
MQSC commands


def qcf(TOPSECURITY_QCF) qmgr(BEAQM) channel(SYSTEM.DEF.SVRCONN) hostname(semp20) port(1421) transport(CLIENT)
def q(TOPSECURITY_QUEUE) queue(TOPSECURITY.QUEUE) qmgr(BEAQM)


You find definition of the MQSC commands either in the "MQseries MQSC Command Reference" or on page 39 in the "MQseries Using Java - MQ 6.0".

"qcf" defines a non-transactional queue connection factory:

TOPSECURITY_QCF/ClassName=com.ibm.mq.jms.MQQueueConnectionFactory
TOPSECURITY_QCF/FactoryName=com.ibm.mq.jms.MQQueueConnectionFactoryFactory
We're using the same queue manager for both non-transactional and transactional interaction. "hostname" is defined as "semp20" (2GHz sempron) and the queue manager operates from port 1421.

JMSAdmin management console start command

JMSAdmin management console

Once having configured the external JNDI provider, you should be able to locate a file c:\jms-jndi\directory\.bindings with plain-text contents as outlined in the following. As a routine check, you'll find the port/machine name from above.


After configuration using JMSAdmin..
c:\jms-jndi-directory\.bindings

#This file is used by the JNDI FSContext.
#Sun Aug 14 16:56:00 CEST 2005
TOPSECURITY_QUEUE/ClassName=com.ibm.mq.jms.MQQueue
TOPSECURITY_QUEUE/FactoryName=com.ibm.mq.jms.MQQueueFactory
TOPSECURITY_QUEUE/RefAddr/0/Content=6
TOPSECURITY_QUEUE/RefAddr/0/Encoding=String
TOPSECURITY_QUEUE/RefAddr/0/Type=VER
TOPSECURITY_QUEUE/RefAddr/1/Content=-2
TOPSECURITY_QUEUE/RefAddr/1/Encoding=String
TOPSECURITY_QUEUE/RefAddr/1/Type=EXP
TOPSECURITY_QUEUE/RefAddr/2/Content=-2
TOPSECURITY_QUEUE/RefAddr/2/Encoding=String
TOPSECURITY_QUEUE/RefAddr/2/Type=PRI
TOPSECURITY_QUEUE/RefAddr/3/Content=-2
TOPSECURITY_QUEUE/RefAddr/3/Encoding=String
TOPSECURITY_QUEUE/RefAddr/3/Type=PER
TOPSECURITY_QUEUE/RefAddr/4/Content=1208
TOPSECURITY_QUEUE/RefAddr/4/Encoding=String
TOPSECURITY_QUEUE/RefAddr/4/Type=CCS
TOPSECURITY_QUEUE/RefAddr/5/Content=0
TOPSECURITY_QUEUE/RefAddr/5/Encoding=String
TOPSECURITY_QUEUE/RefAddr/5/Type=TC
TOPSECURITY_QUEUE/RefAddr/6/Content=273
TOPSECURITY_QUEUE/RefAddr/6/Encoding=String
TOPSECURITY_QUEUE/RefAddr/6/Type=ENC
TOPSECURITY_QUEUE/RefAddr/7/Content=1
TOPSECURITY_QUEUE/RefAddr/7/Encoding=String
TOPSECURITY_QUEUE/RefAddr/7/Type=FIQ
TOPSECURITY_QUEUE/RefAddr/8/Content=TOPSECURITY.QUEUE
TOPSECURITY_QUEUE/RefAddr/8/Encoding=String
TOPSECURITY_QUEUE/RefAddr/8/Type=QU
TOPSECURITY_QUEUE/RefAddr/9/Content=BEAQM
TOPSECURITY_QUEUE/RefAddr/9/Encoding=String
TOPSECURITY_QUEUE/RefAddr/9/Type=QMGR
TOPSECURITY_QCF/ClassName=com.ibm.mq.jms.MQQueueConnectionFactory
TOPSECURITY_QCF/FactoryName=com.ibm.mq.jms.MQQueueConnectionFactoryFactory
TOPSECURITY_QCF/RefAddr/0/Content=6
TOPSECURITY_QCF/RefAddr/0/Encoding=String
TOPSECURITY_QCF/RefAddr/0/Type=VER
TOPSECURITY_QCF/RefAddr/1/Content=1
TOPSECURITY_QCF/RefAddr/1/Encoding=String
TOPSECURITY_QCF/RefAddr/1/Type=TRAN
TOPSECURITY_QCF/RefAddr/10/Content=false
TOPSECURITY_QCF/RefAddr/10/Encoding=String
TOPSECURITY_QCF/RefAddr/10/Type=SFIPS
TOPSECURITY_QCF/RefAddr/11/Content=false
TOPSECURITY_QCF/RefAddr/11/Encoding=String
TOPSECURITY_QCF/RefAddr/11/Type=SPAG
TOPSECURITY_QCF/RefAddr/12/Content=true
TOPSECURITY_QCF/RefAddr/12/Encoding=String
TOPSECURITY_QCF/RefAddr/12/Type=UCP
TOPSECURITY_QCF/RefAddr/13/Content=5000
TOPSECURITY_QCF/RefAddr/13/Encoding=String
TOPSECURITY_QCF/RefAddr/13/Type=PINT
TOPSECURITY_QCF/RefAddr/14/Content=10
TOPSECURITY_QCF/RefAddr/14/Encoding=String
TOPSECURITY_QCF/RefAddr/14/Type=MBS
TOPSECURITY_QCF/RefAddr/15/Content=1
TOPSECURITY_QCF/RefAddr/15/Encoding=String
TOPSECURITY_QCF/RefAddr/15/Type=FIQ
TOPSECURITY_QCF/RefAddr/16/Content=
TOPSECURITY_QCF/RefAddr/16/Encoding=String
TOPSECURITY_QCF/RefAddr/16/Type=LA
TOPSECURITY_QCF/RefAddr/17/Content=5000
TOPSECURITY_QCF/RefAddr/17/Encoding=String
TOPSECURITY_QCF/RefAddr/17/Type=RINT
TOPSECURITY_QCF/RefAddr/18/Content=true
TOPSECURITY_QCF/RefAddr/18/Encoding=String
TOPSECURITY_QCF/RefAddr/18/Type=TCM
TOPSECURITY_QCF/RefAddr/19/Content=SYSTEM.DEFAULT.MODEL.QUEUE
TOPSECURITY_QCF/RefAddr/19/Encoding=String
TOPSECURITY_QCF/RefAddr/19/Type=TM
TOPSECURITY_QCF/RefAddr/2/Content=BEAQM
TOPSECURITY_QCF/RefAddr/2/Encoding=String
TOPSECURITY_QCF/RefAddr/2/Type=QMGR
TOPSECURITY_QCF/RefAddr/20/Content=
TOPSECURITY_QCF/RefAddr/20/Encoding=String
TOPSECURITY_QCF/RefAddr/20/Type=TQPFX
TOPSECURITY_QCF/RefAddr/21/Content=1
TOPSECURITY_QCF/RefAddr/21/Encoding=String
TOPSECURITY_QCF/RefAddr/21/Type=MRET
TOPSECURITY_QCF/RefAddr/3/Content=semp20
TOPSECURITY_QCF/RefAddr/3/Encoding=String
TOPSECURITY_QCF/RefAddr/3/Type=HOST
TOPSECURITY_QCF/RefAddr/4/Content=1421
TOPSECURITY_QCF/RefAddr/4/Encoding=String
TOPSECURITY_QCF/RefAddr/4/Type=PORT
TOPSECURITY_QCF/RefAddr/5/Content=SYSTEM.DEF.SVRCONN
TOPSECURITY_QCF/RefAddr/5/Encoding=String
TOPSECURITY_QCF/RefAddr/5/Type=CHAN
TOPSECURITY_QCF/RefAddr/6/Content=819
TOPSECURITY_QCF/RefAddr/6/Encoding=String
TOPSECURITY_QCF/RefAddr/6/Type=CCS
TOPSECURITY_QCF/RefAddr/7/Content=\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000
TOPSECURITY_QCF/RefAddr/7/Encoding=String
TOPSECURITY_QCF/RefAddr/7/Type=CT
TOPSECURITY_QCF/RefAddr/8/Content=0
TOPSECURITY_QCF/RefAddr/8/Encoding=String
TOPSECURITY_QCF/RefAddr/8/Type=CTO
TOPSECURITY_QCF/RefAddr/9/Content=0
TOPSECURITY_QCF/RefAddr/9/Encoding=String
TOPSECURITY_QCF/RefAddr/9/Type=SRC



If your .bindings file looks messy, you can do a sort <.bindings>.bindings.sorted to obtain a better structure. It won't affect the functionality - and looks a lot nicer. Please take notice of "TRAN=1" which is caused by the setting "transport(CLIENT)" or "tran(CLIENT)". That's the only possiblity when not connecting to MQ from the same machine with the MQ installation. Now, the MQ should be set up to facilitate communications. We need a couple of commandline clients to facilitate direct operations...


First from command-line to MQ
ToMQnative.java

package dk.topsecurity;

//import javax.jms.*;
import java.util.Date;
import java.util.Hashtable;

import javax.jms.DeliveryMode;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.directory.InitialDirContext;

import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQQueueSender;
import com.ibm.mq.jms.MQQueueSession;

public class ToMQnative implements ExceptionListener {

/** 
 * Setting up authorisation username. Used by classes in com.ibm.mqjms.jar
 * Setting up queue connection factory (QCF)
 * Setting up name of queue, as defined in the MQ setup
 * Setting up url for file-based, external JNDI provider 
 * Setting up context factory to use with external JNDI
 */

  public String mq_username = "Administrator";
  public String mq_qcf = "TOPSECURITY_QCF";
  public String mq_qname = "TOPSECURITY.QUEUE";
  public String mq_url = "file:/C:/jms-jndi-directory";
  public String mq_jndi =  "com.sun.jndi.fscontext.RefFSContextFactory";

/**
 * main method - binding to the Websphere MQ installation - and delivering a
 * number of messages.
 *
 * Make sure you've run the MQSC commands on MQ before deploying examples
 *
 * define qcf(TOPSECURITY_QCF) qmgr(BEAQM) channel(SYSTEM.DEF.SVRCONN) hostname(semp20) port(1421) transport(CLIENT)
 * define q(TOPSECURITY.QUEUE) queue(TOPSECURITY.QUEUE) qmgr(BEAQM)
 */
 
  public static void main(String[] args) {

    ToMQnative sender = null;
    try {
      sender = new ToMQnative();
      sender.setupQueueConnection();
      for(int i=0;;i++) {
        sender.send(sender.setMessage("Hello no "+i+" from client at "+new Date()));
        Thread.sleep(1000L);
      }
    }
    catch(JMSException je) {
      System.out.println("Caught JMSException: "+je);
      Exception le = je.getLinkedException();
      if (le != null) 
        System.out.println("Linked exception: "+le);
      je.printStackTrace();
    } catch(Exception e) {
       e.printStackTrace();
     } finally {
      try {
      if (sender != null)
        sender.cleanup();
      } catch (Exception e) { }
    }
  }

  private void setupQueueConnection() throws Exception {

    //set the username which to use for authentication
    System.out.println("Initial user.name="+System.getProperty("user.name"));
    System.setProperty("user.name",mq_username);
    System.out.println("Authrorisation required user.name="+System.getProperty("user.name"));

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, mq_jndi);
    env.put(Context.PROVIDER_URL, mq_url);

    InitialDirContext ctx = new InitialDirContext(env);
    com.ibm.mq.jms.MQQueueConnectionFactory factory =
            (com.ibm.mq.jms.MQQueueConnectionFactory)ctx.lookup(mq_qcf);

    System.out.println("Factory = " +factory);

    /* Create a QueueConnection, QueueSession
     * When a connection is made, use the createQueueSession method on the
     * QueueConnection to obtain a session. Parameters: 
     * boolean= determines whether the session is transacted or non-transacted.
     * int =  that determines the acknowledge mode.
     * Simplest case is that of the non-transacted session with AUTO_ACKNOWLEDGE
     * - p319 in the IBM redbook.
     */
    connection = (MQQueueConnection)factory.createQueueConnection();
    session = (MQQueueSession)connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    
    ioQueue = new MQQueue();
    ioQueue.setBaseQueueName(mq_qname);
    ioQueue.setPersistence(DeliveryMode.PERSISTENT);

    connection.start();
    connection.setExceptionListener(this);

    queueSender = (MQQueueSender)session.createSender(ioQueue);
  }


  /**
   * For test purpose, create one of many possible types of messages: 
   * BytesMessage, MapMessage, ObjectMessage, StreamMessage
   */
  TextMessage setMessage(String text) throws Exception {

    TextMessage msg = session.createTextMessage();
    msg.setText(text);
    return(msg);
  }

  /**
   * Send message off to MQ
   */
  void send(TextMessage msg) throws Exception {

    System.out.println("To " + ioQueue.getQueueName() + " sending message=" + msg.getText());
    queueSender.send(msg);
  }

  /**
   * required in the ExceptionListener interface
   */
  public void onException(JMSException jms) {
    System.out.println("onException: jms" + jms);
    jms.printStackTrace();
  }

  /**
   * do away with connections to MQ
   */
  void cleanup() throws Exception {
    if (session != null) {
      session.close();
      session = null;
    }
    if (connection != null)
      connection.close();
      connection = null;
  }

  private MQQueue ioQueue;
  private MQQueueConnectionFactory factory;
  private MQQueueSession session;
  private MQQueueConnection connection;
  private MQQueueSender queueSender;
  private InitialContext ctx;
  private TextMessage msg;

}



And the other way around... from MQ to the command-line client...


From MQ to J2EE stand-alone client
FromMQnative.java

package dk.topsecurity;

//import javax.jms.*;
import java.util.Hashtable;

import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageEOFException;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.directory.InitialDirContext;

import com.ibm.jms.JMSBytesMessage;
import com.ibm.jms.JMSTextMessage;
import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQQueueReceiver;
import com.ibm.mq.jms.MQQueueSession;

import javax.naming.*;
import javax.naming.directory.*;

public class FromMQnative implements MessageListener, ExceptionListener {

/** 
 * Setting up authorisation username. Used by classes in com.ibm.mqjms.jar
 * Setting up queue connection factory (QCF)
 * Setting up name of queue, as defined in the MQ setup
 * Setting up url for file-based, external JNDI provider 
 * Setting up context factory to use with external JNDI
 */

  public String mq_username = "Administrator";
  public String mq_qcf = "TOPSECURITY_QCF";
  public String mq_qname = "TOPSECURITY.QUEUE";
  public String mq_url = "file:/C:/jms-jndi-directory";
  public String mq_jndi =  "com.sun.jndi.fscontext.RefFSContextFactory";

/**
 * main method - binding to the Websphere MQ installation - and delivering a
 * number of messages.
 *
 * Make sure you've run the MQSC commands on MQ before deploying examples
 *
 * define qcf(TOPSECURITY_QCF) qmgr(BEAQM) channel(SYSTEM.DEF.SVRCONN) hostname(semp20) port(1421) transport(CLIENT)
 * define q(TOPSECURITY.QUEUE) queue(TOPSECURITY.QUEUE) qmgr(BEAQM)
 */
 
  public static void main(String[] args) {

/*
    if (args.length < 1 || args.length > 2) {
    System.out.println("call with parameters [queue]");
      return;
    } 
*/
    FromMQnative client = null;
    try {
      client = new FromMQnative();
      client.setupQueueConnection();
      synchronized (client) {
        for(;;) {
          try {
            client.wait();
          } 
          catch (InterruptedException ie) {}
      } }
   // client.close();
    }
    catch(JMSException je) {
      System.out.println("Caught JMSException: "+je);
      Exception le = je.getLinkedException();
      if (le != null) 
        System.out.println("Linked exception: "+le);
      je.printStackTrace();
    } catch(Exception e) {
       e.printStackTrace();
    } finally {
      try {
      if (client != null)
        client.cleanup();
      } catch (Exception e) { }
    }
  }

  private void setupQueueConnection() throws Exception {

    //set the username which to use for authentication
    System.out.println("Initial user.name="+System.getProperty("user.name"));
    System.setProperty("user.name",mq_username);
    System.out.println("Authrorisation required user.name="+System.getProperty("user.name"));

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, mq_jndi);
    env.put(Context.PROVIDER_URL, mq_url);

    InitialDirContext ctx = new InitialDirContext(env);    
    com.ibm.mq.jms.MQQueueConnectionFactory factory =
            (com.ibm.mq.jms.MQQueueConnectionFactory)ctx.lookup(mq_qcf);

    System.out.println("Factory = " +factory);

    /* Create a QueueConnection, QueueSession
     * When a connection is made, use the createQueueSession method on the
     * QueueConnection to obtain a session. Parameters: 
     * boolean= determines whether the session is transacted or non-transacted.
     * int =  that determines the acknowledge mode.
     * Simplest case is that of the non-transacted session with AUTO_ACKNOWLEDGE
     * - p319 in the IBM redbook.
     */
    connection = (MQQueueConnection)factory.createQueueConnection();
    session = (MQQueueSession)connection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);


    try {
      ioQueue = (MQQueue)ctx.lookup(mq_qname);
      System.out.println("Looked up MQQueue");
    } catch (NamingException ne) {
      System.out.println("Created new MQQueue");
      ioQueue = new MQQueue();
      ioQueue.setBaseQueueName(mq_qname);
      ioQueue.setPersistence(DeliveryMode.PERSISTENT);
      ctx.bind(mq_qname, ioQueue);
    } 

    // If you want to produce a raw MQ message then
    // ioQueue.targetClient must be set to JMSC.MQJMS_CLIENT_NONJMS_MQ
    // as the target client is WMQ and not a JMS application.
    //   This causes the message to be produced without an MQRFH2
    //
    //ioQueue.setTargetClient(com.ibm.mq.jms.JMSC.MQJMS_CLIENT_NONJMS_MQ);

    String selector = "";
    receiver = (MQQueueReceiver)session.createReceiver(ioQueue,selector);
    receiver.setMessageListener(this);
    connection.start();

    System.out.println("JMS listener ready to recieve messages from: " + ioQueue);

  }


  public void onMessage(Message jmsMsg) {
    
    try { //deal with TextMessage,BytesMessage - and discharge the rest..
     if (jmsMsg instanceof JMSTextMessage) {
        String msgText = ((JMSTextMessage) jmsMsg).getText();
        System.out.println("JMSTextMessage:" + msgText);
     } else 
        if (jmsMsg instanceof JMSBytesMessage) {
          // put it in a TypedCArray and try to send it to console anyway
          byte[] carray = new byte[1000];
          for (int i=0;;i++) { //rean until eof
            try {
                carray[i] = (byte) ((JMSBytesMessage) jmsMsg).readByte();
            } catch (MessageEOFException eof) {
                System.out.println("JMSBytesMessage: " + i + " bytes.");
                break;
            }
          }
          for (int i = 0; i<10 ; i++) {
            System.out.println("  CArray[" + i + "] = " + carray[i]);
            if(carray[i] == 0) break;
          }   // end for
        } else
    	     if (jmsMsg instanceof TextMessage) {
    	         String msgText = ((TextMessage) jmsMsg).getText();
    	         System.out.println("TextMessage:" + msgText);
    	      } else 
    	         if (jmsMsg instanceof BytesMessage) {
    	           // put it in a TypedCArray and try to send it to console anyway
    	           byte[] carray = new byte[1000];
    	           for (int i=0;;i++) { //rean until eof
    	             try {
    	                 carray[i] = (byte) ((BytesMessage) jmsMsg).readByte();
    	             } catch (MessageEOFException eof) {
   	    	             System.out.println("BytesMessage: " + i + " bytes.");
    	                 break;
    	           } }
    	           for (int i = 0; i<10 ; i++) {
    	             System.out.println("  CArray[" + i + "] = " + carray[i]);
    	             if(carray[i] == 0) break;
    	           }   // end for
    	         } else {
    	           System.out.println("Message type not of type TextMessage or BytesMessage");
    	         }
        
    	  
    } catch (JMSException jmse) {
      jmse.printStackTrace();
    }
  } 

  /**
   * required in the ExceptionListener interface
   */
  public void onException(JMSException jms) {
    System.out.println("onException: jms" + jms);
    jms.printStackTrace();
  }

  /**
   * do away with connections to MQ
   */
  void cleanup() throws Exception {
    if (session != null) {
      session.close();
      session = null;
    }
    if (connection != null)
      connection.close();
      connection = null;
  }

  private MQQueue ioQueue;
  private MQQueueConnectionFactory factory;
  private MQQueueSession session;
  private MQQueueConnection connection;
  private MQQueueReceiver receiver;
  private InitialContext ctx;
  private TextMessage msg;

}



Compile using the MQ libraries: And running the client (stop sender with Ctrl-break)...

ToMQnative sending messages to MQ

FromMQnative receiving messages from MQ

So... what basicly happens is that the command-line client (knowing nothing about Weblogic) sends off messages directly to MQ using support layer jar-files. Once messages have arrived into MQ, the command-line MQ listener client grabs the messages and prints contents to the console.

Basicly this example demonstrates most basic aspects of MQ interfacing :
/topsecurity.dk 2006-5-15