C H A P T E R  13

Using the MQ-JMS Bridge


Note - Read Chapter 12 before reading this chapter.



The Sun MTP MQ-JMS Bridge provides a mapping between the Sun MTP MQSeries trigger mechanism and applications developed to the Java Message Service (JMS) API. The MQ-JMS Bridge is responsible for handling the MQSeries trigger message initiated by the Sun MTP unikixqm daemon and forwarding the associated application messages to a configured user application program. The JMS point-to-point model is used as the underlying JMS messaging style.

At a high level, this provides an abstraction of the transaction initiation mechanism. The target application is oblivious to the means of initiation, and it is only interested in the application message that describes the work to be performed. At a lower level, this relieves the application developer from having to manage the underlying MQSeries queue manager and application queue. The application only needs to respond to invocations to the application implementation of the JMS MessageListener.onMessage() method.

This chapter contains the following topics:


How the MQ-JMS Bridge Works

The MQ-JMS Bridge is built upon the existing MQSeries trigger framework. In this framework, the unikixqm daemon is notified whenever an MQSeries trigger message is placed on the monitored queue. unikixqm then initiates a specified Sun MTP transaction to process the associated application queue. This framework is enhanced by defining the MQ-JMS Bridge as the initial application, rather than a user application, thereby providing a level of indirection to the processing flow.

The MQ-JMS Bridge is responsible for processing the MQSeries trigger message and using the supplied information to access the application queue and obtain an instance of the user application program. The MQ-JMS Bridge then processes the application queue, reading each message and passing it on to the user JMS application through its MessageListener.onMessage method. The following figure shows the basic concept.

  FIGURE 13-1 MQ-JMS Bridge Process Flow

Diagram showing a client application placing a message on the data queue. [ D ]

The elements shown in FIGURE 13-1 are:

Client Application: Creates messages on the input data queue. The client application is independent of Sun MTP.

Data Queue: Places trigger messages on the trigger queue that define Sun MTP transactions.

Trigger Queue: Receives automated messages through procedures configured in the queue manager. Trigger messages contain information used by Sun MTP to start transactions, and used by the transaction processors to find the original data messages that spawned the trigger event.

unikixqm: Monitors the trigger queue and starts the transaction based on the Application ID in the trigger message. In the case of JMS application transactions, the transaction started by unikixqm is always the MQ-JMS Bridge.

MQ-JMS Bridge: Responsible for retrieving messages from the data queue and starting the appropriate JMS application, supplying the data message upon invocation.

JMS Application: Implements the MessageListener interface and, therefore, must supply an onMessage method with one parameter of type Message. The JMS application received the original data message from the data queue through the MQ-JMS Bridge. Any further interaction with MQSeries is the responsibility of the JMS application. It can create connects to the queue manager using the same configuration information used by the MQ-JMS Bridge. See the GetAliasJMSListenerEXMQJMS sample program in the $UNIKIX/test/mq/jms directory for an example of queue manager interaction from a JMS application.


Defining MQ-JMS Bridge Attributes

The MQ-JMS Bridge extends the MQSeries trigger configuration shown in CODE EXAMPLE 12-1 to define the target user application that will be scheduled when a new trigger message is generated.

To define the user application, use either of these methods:

The configuration shown in this example causes the unikixqm daemon to initiate the MQJV transaction. The message that starts the transaction contains the trigger properties information, which includes the USERDATA attribute specifying the target application name scouser.GetAliasJMSListenerExMQJMS.


Configuring the Region

This section describes how to configure your region to use the MQ-JMS Bridge.

Before configuring the MQ-JMS Bridge, you must:

To configure the MQ-JMS Bridge itself, you must perform these tasks:

Defining the jms Group in the GCT

The program associated with the MQ-JMS Bridge product is assigned to the jms group. To enable your region to access this program, you must define the jms group in the GCT.


procedure icon  To Define the jms Group

1. In the Table Manager, open the GCT and press PF4 to insert an entry.

2. On the insert screen, type jms as the group name and $KIXSYS/jms.dir as the directory.

See FIGURE 13-2.

  FIGURE 13-2 Defining the JMS Group in the GCT

Screen shot showing how to define the jms group in the GCT.

3. Press Enter to insert the entry and return to the GCT main screen.

4. Press PF2 to write the changes to disk.

5. Exit the Table Manager.

6. Shut down and restart the region so your changes take effect.


procedure icon  To View MQ-JMS Bridge Program Information

1. Open the PPT and put your cursor on the JMQJMSB program entry.

2. Press PF9 to open the Java Class Details screen.

The fully qualified class path for the MQ-JMS Bridge application is displayed on this screen. The program JMQJMSB is associated with the Java class file named com.sun.emp.mtp.MQJMS.MQJMSBridge.

FIGURE 13-3 shows the Java Class Details screen for the JMQJMSB program.

  FIGURE 13-3 MQ-JMS Bridge Entry in the PPT

Screen shot showing the PPT Java Class Details screen entry for the JMQJMSB program.

procedure icon  To Associate a Transaction ID With the MQ-JMS Bridge Program



Note - The PCT for the sample application in $UNIKIX/test/mq/jms already contains the entries described here.



1. Open the PCT and press PF4 to insert an entry.

2. Type JMQJMSB in the Program field.

3. Type a transaction identifier in the Trans ID field.

FIGURE 13-4 shows the JMQJMSB program is assigned to the MQJV transaction. JMQJMSB must be the first program executed when the transaction ID is issued.

This transaction ID must match the Application ID in the MQSeries trigger configuration. For example, the transaction ID shown in the following figure (MQJV) matches the value set in APPLICID shown in CODE EXAMPLE 13-1.

  FIGURE 13-4 MQ-JMS Bridge Entry in the PCT

Screen shot showing the PCT entry for the JMQJMSB program.

4. Press Enter to insert the entry.

5. Press PF2 to save the table to disk.

6. Shut down and restart the region.

Now there is a relationship between the MQSeries trigger queue and the MQ-JMS Bridge application.

Specifying the MQ-JMS Bridge Properties

The MQ-JMS Bridge uses a configuration file that contains attributes for the product. The configuration file attributes that can be applied at two levels:

The attributes at the overall level are typically related to MQSeries-specific configuration, such as the queue manager location. Application attributes enable the mapping feature whereby a target application can be mapped to some other application before the MQ-JMS Bridge attempts to locate an instance.



Note - Maintaining the MQJMS.properties file in the $KIXSYS/kix_java directory enables each Sun MTP region to have a unique MQ-JMS configuration.




procedure icon  To Define the Property File

1. Copy the $UNIKIX/lib/kix_java/MQJMS.properties file to your region's $KIXSYS/kix_java directory.

See Customizing the Classpath and Library Path for instructions on creating the kix_java directory.

2. Modify the file to meet your site requirements.

The configuration file follows the Java property file format, using a series of
key=value string pairs. The following table describes the overall attributes and their default values.

TABLE 13-1 MQJMS.properties File

Attribute Name

Default Value

Description

application

Value of MQTM-USERDATA

(default application)

Fully qualified class name of user application to be loaded for this request. This value is only used if MQTM-USERDATA is not defined in the trigger message (that is, it has a value of spaces). Can be modified using the application mapping feature of the MQ-JMS Bridge.

channel

CHANNEL1

Name of the server channel to use to connect to the MQSeries queue manager.

host

localhost

Name/address of the server where the MQSeries queue manager is executing.

port

1414

Port number used by the MQSeries queue manager.

debug

no

Specifies whether or not MQ-JMS Bridge processing events will be logged to the unikixmain.dbg file. Supported values are:

yes: Perform logging

no: Do not perform logging

See Debugging Information for information about the types of processing events that are logged.

txscope

message

Specifies the scope of the Sun MTP unit-of-work. Supported value is message, which specifies that each message is processed within a single Sun MTP unit-of-work. That is, each successful onMessage() invocation is followed by a SYNCPOINT (Task.commit()).


Regardless of the type of MQSeries triggering used (FIRST, EVERY, or DEPTH), the user JMS application deployed in Sun MTP (the consumer of the application messages) is unaware of the messages on the MQSeries queue. The user JMS application is invoked for each message that is retrieved from the MQSeries queue and there is no correlation between successive invocations. For the user JMS application to envelope each onMessage() invocation in a separate Sun MTP unit-of-work, the txscope attribute of the MQ-JMS Bridge properties file can be set to the value message.



Note - In this release, the only valid attribute for txscope is message.



If the Sun MTP region and MQSeries queue manager are executing on the same host, there is a single MQSeries queue manager configured that acts as the default queue manager. In this case, if no application mapping is required, no MQ-JMS Bridge configuration file is needed. The sample application in $UNIKIX/test/mq/jms is based on this scenario.

If the Sun MTP region and MQSeries queue manager are on different hosts, the MQSeries queue manager has a special channel defined for communication between the MQSeries client applications (unikixqm and the MQ-JMS Bridge in this case) and the queue manager. The MQJMS.properties file must contain the host and channel values defined in the MQSERVER environment variable. For example, if MQSERVER=MYSVRCHNL/TCP/myserver, the MQJMS.properties file must contain the following entries:

host=myserver
channel=MYSVRCHNL

In general, the MQ-JMS Bridge configuration file will mirror parameters defined for the unikixqm process in the unikixrc.cfg file and in the MQSERVER environment variable. Java retrieves the MQSeries configuration from this properties file, rather than from the runtime environment. See To Configure the Region to Use MQSeries for information about $MQSERVER.

Application Mapping

Application mapping is the technique of mapping one application target to some other target. For example, it enables an application identified as MQJMSAppl_GetAlias to be replaced by one identified as scouser.GetAliasJMSListener.

When using mapping, the target user JMS application is defined in the MQJMS.properties file rather than explicitly in the MQSeries PROCESS definition by the USERDATA attribute. This enables you to change the back-end application by simply changing the single MQJMS.properties file instead of the many MQSeries PROCESS definitions that might exist.

To implement application mapping, specify a token or alias, rather than the fully qualified class name of the user application, in the USERDATA attribute of the MQSeries PROCESS definition. This token is defined in the MQJMS.properties file as a key with the target application defined as the corresponding value.

CODE EXAMPLE 13-2 shows how the MQJMSAppl_GetAlias logical token is mapped to the JMS application scouser.GetAliasJMSListener.

CODE EXAMPLE 13-2 Application Mapping
MQSeries Configuration
  DEF PROCESS (MQJV.TRIGGER.PROC) REPLACE        +
	DESCR ('Invoke instance of MQJMSBridge')  +
	USERDATA ('MQJMSAppl_GetAlias')           +
	APPLICID (MQJV)                           +
	APPLTYPE (CICS)
 
MQ-JMS Bridge (MQJMS.properties) file
  MQJMSAppl_GetAlias=scouser.GetAliasJMSListener



Note - The USERDATA attribute could contain a real application target, such as scouser.GetAliasJMSListener. See CODE EXAMPLE 13-1.



See Processing Flow for more information about how application mapping works.

Configuring the Classpath

The JCICS framework uses the Sun MTP environment variable KIXPROGS to establish an application classpath attribute to the JVM. Typically, this is how user Java applications are configured in the region, and it is how the user JMS applications should be defined to the region. The MQ-JMS Bridge application is a system application and as such, is configured in Sun MTP as part of the standard Sun MTP system JAR files.

The MQSeries MQ-JMS archive files (com.ibm.mqjms.jar and com.ibm.mq.jar) and the Sun archives (jms.jar and jndi.jar) must be available for the JVM to successfully load the MQ-JMS Bridge application. The archives must be defined by using the Classpath.appends file.

The Classpath.appends file must be placed in the $KIXSYS/kix_java directory. By editing this file and adding the necessary directory files (for example, /opt/mqm/java/lib/com.ibm.mqjms.jar), the dependent archives can be accessed by the JVM. See Customizing the Classpath and Library Path for instructions on setting up the kix_java directory and its contents.

Configuring the Library Path

You must also place the Libpath.appends file in the $KIXSYS/kix_java directory. You must include the following path in this file:

MQ-installdir/java/lib

where MQ-installdir is the directory where MQSeries is installed. You must also add the paths to any other libraries needed by the JVM.

Configuring the MQSERIES Environment Variable

To use the MQ-JMS Bridge, you must set the MQSERIES environment variable to:

MQ-installdir/java/lib

where MQ-installdir is the directory where MQSeries is installed. This is different from the setting when you are using MQSeries without the MQ-JMS Bridge (see Chapter 12).


Processing Flow

The high-level flow of control for each trigger message is as follows:

1. Retrieve the MQSeries trigger message.

2. Load an instance of the specified JMS application.

3. Access the specified application queue.

4. For each message in the application queue:

a. Read the message body.

b. Invoke the application MessageListener.onMessage(Message) method.

  FIGURE 13-5 MQ-JMS Bridge Configuration Without Application Mapping

Diagram showing an MQ-JMS application without application mapping.[ D ]

  FIGURE 13-6 MQ-JMS Bridge Configuration With Application Mapping

Diagram showing an MQ-JMS application with application mapping.[ D ]


Debugging Information

If you set the debug attribute to yes in the MQJMS.properties file, logging information is written to the $KIXSYS/unikixmain.dbg file. An example of each type of event entry is shown in the following sections.

Refer to the IBM MQSeries documentation and the IBM MQ-JMS documentation for detailed information about these events.

Triggered transaction start Event

At the start of the transaction, the MQJMS.properties arguments are listed:

07/25/2001 14:58:08 MQJMSBridge :Triggered transaction start:
Check MQJMS.properties File:
	chan=CHANNEL1
	host=nacelle
	port=1414
	txscope=message

Get Trigger Msg Event

This entry lists the format of the received trigger message:

07/25/2001 14:58:08 MQJMSBridge :Get Trigger Msg:
STRUCID=TM
VERSION=
QNAME=UNIKIXMQ1
PROCESSNAME=MQJV.TRIGGER.PROC
TRIGGERDATA=Trigdata from UNIKIXMQ1
APPLTYPE=
APPLID=MQJV
ENVDATA=Environ for MQJV
USERDATA=
QMGR-NAME=TESTQM

Target application Event

This entry lists the target application to be accessed:

07/25/2001 14:58:08 MQJMSBridge :Target application:
	scouser.GetAliasJMSListenerExMQJMS

Receiver queue started Event

The following entry names the connected receiver queue:

07/25/2001 14:58:10 MQJMSBridge :Receiver queue started: queue:///UNIKIXMQ1

Process 'onMessage' Event

The onMessage event entry lists details about the input message passed to the onMessage() method of the target application. Each started event entry is followed by a unit-of-work commit entry (see Unit-of-Work Commit complete Event).

The following example is a byte message:

07/25/2001 14:58:10 MQJMSBridge :Process 'onMessage':
07/25/2001 14:58:10 MQJMSBridge :
07/25/2001 14:58:10 MQJMSBridge :JMS Message class: jms_bytes
07/25/2001 14:58:10 MQJMSBridge :  JMSType:         null
07/25/2001 14:58:10 MQJMSBridge :  JMSDeliveryMode: 2
07/25/2001 14:58:10 MQJMSBridge :  JMSExpiration:   0
07/25/2001 14:58:10 MQJMSBridge :  JMSPriority:     0
07/25/2001 14:58:10 MQJMSBridge :  JMSMessageID:    ID:414d512054455354514d20202020202016405f3b13100000
07/25/2001 14:58:10 MQJMSBridge :  JMSTimestamp:    996098078560
07/25/2001 14:58:10 MQJMSBridge :  JMSCorrelationID:null
07/25/2001 14:58:10 MQJMSBridge :  JMSDestination:  null
07/25/2001 14:58:10 MQJMSBridge :  JMSReplyTo:      null
07/25/2001 14:58:10 MQJMSBridge :  JMSRedelivered:  false
07/25/2001 14:58:10 MQJMSBridge :  JMS_IBM_Encoding:546
07/25/2001 14:58:10 MQJMSBridge :  JMSXAppID:S7.2.0/test/mq/kixmqtst
07/25/2001 14:58:10 MQJMSBridge :  JMS_IBM_Format:
07/25/2001 14:58:10 MQJMSBridge :  JMS_IBM_PutApplType:11
07/25/2001 14:58:10 MQJMSBridge :  JMS_IBM_MsgType:8
07/25/2001 14:58:10 MQJMSBridge :  JMSXUserID:R_Holbert
07/25/2001 14:58:10 MQJMSBridge :  JMSXDeliveryCount:1
07/25/2001 14:58:10 MQJMSBridge :  JMS_IBM_Character_Set:437
07/25/2001 14:58:10 MQJMSBridge :Integer encoding: 2, Floating point encoding 512
07/25/2001 14:58:10 MQJMSBridge :48756d7074792044756d70747920536d69746820

The following example is a text message:

07/25/2001 14:58:57 MQJMSBridge :Process 'onMessage':
07/25/2001 14:58:57 MQJMSBridge :
07/25/2001 14:58:57 MQJMSBridge :JMS Message class: jms_text
07/25/2001 14:58:57 MQJMSBridge :  JMSType:         null
07/25/2001 14:58:57 MQJMSBridge :  JMSDeliveryMode: 1
07/25/2001 14:58:57 MQJMSBridge :  JMSExpiration:   0
07/25/2001 14:58:57 MQJMSBridge :  JMSPriority:     0
07/25/2001 14:58:57 MQJMSBridge :  JMSMessageID:    ID:414d512054455354514d20202020202016405f3b13400000
07/25/2001 14:58:57 MQJMSBridge :  JMSTimestamp:    996098215350
07/25/2001 14:58:57 MQJMSBridge :  JMSCorrelationID:null
07/25/2001 14:58:57 MQJMSBridge :  JMSDestination:  null
07/25/2001 14:58:57 MQJMSBridge :  JMSReplyTo:      null
07/25/2001 14:58:57 MQJMSBridge :  JMSRedelivered:  false
07/25/2001 14:58:57 MQJMSBridge : JMSXAppID:amqsputc_nd\300\200\300\200\300\200
\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200\300\200
\300\200\300\200\300\200\300\200
07/25/2001 14:58:57 MQJMSBridge :  JMS_IBM_Format:MQSTR
07/25/2001 14:58:57 MQJMSBridge :  JMS_IBM_PutApplType:6
07/25/2001 14:58:57 MQJMSBridge :  JMS_IBM_MsgType:8
07/25/2001 14:58:57 MQJMSBridge :  JMSXUserID:R_Holbert
07/25/2001 14:58:57 MQJMSBridge :  JMSXDeliveryCount:1
07/25/2001 14:58:57 MQJMSBridge :Clark Kent

Unit-of-Work Commit complete Event

This entry indicates that a commit was done on behalf of the target application:

07/25/2001 14:58:11 MQJMSBridge :Unit-of-Work Commit complete.

State of Receiver queue is now 'empty' Event

This entry indicates that the receiver queue has no more messages on it:

07/25/2001 14:58:11 MQJMSBridge :State of Receiver queue is now 'empty'

Close Receiver queue and wrap-up Event

Because the receiver queue is empty, the MQ-JMS Bridge will close down the input queue:

07/25/2001 14:58:11 MQJMSBridge :Close Receiver queue and wrap-up

Wrap-up successful Event

The triggered transaction cycle is complete. If a new message arrives on the receiver queue, the MQSeries service will build a new trigger message and the entire sequence starts over.

07/25/2001 14:58:11 MQJMSBridge :Wrap-up successful


Running the MQ-JMS Bridge Sample Application

The MQ-JMS Bridge sample application is located in the $UNIKIX/test/mq/jms directory. The following README.doc file contains the instructions for setting up your region and running the application.

CODE EXAMPLE 13-3 MQ-JMS Bridge README.doc File

#**********************************************************************#
#*                                                                    *#
#* Copyright (c) 2001 by Sun Microsystems, Inc.                       *#
#* All rights reserved.                                               *#
#*                                                                    *#
#**********************************************************************#
 
Introduction
------------
This sample Java JMS application demonstrates the use of a JCICS transaction
triggered by the MQSeries trigger monitoring facility.
 
The application is a simple one that takes a person's name as input and
goes against another JCICS program that returns the corresponding alias for that
name. The name and alias together constitute the resulting output message.
 
The application program name is: GetAliasJMSListener
	This program demonstrates: use of the JMS API
	                           use of the JCICS API
	The output message is placed in 'unikixmain.log'
 
A similar more complex application is named: GetAliasJMSListenerExMQJMS
	This program demonstrates: same thing as GetAliasJMSListener,
                                  in addition it also demonstrates the
                                  use of the IBM MQSeries JMS API for
                                  opening a connection to an MQSeries
                                  output queue for placement of the
                                  output message.
	The output message is placed on an MQSeries queue.
 
Files in $UNIKIX/test/mq/jms
-------------------------------
	### Java JMS application Sources ###
	------------------------------------
		GetAliasJMSListener.java
		GetAliasJMSListenerExMQJMS.java
		GetAlias.java
		GetAliasCommAreaRecord.java
		GetAliasDPL.java
		GetAliasInMemoryStore.java
		NameAlias.java
 
	### Resource Control Tables for the Sun MTP region ###
	------------------------------------------------------
		gct.tbl
		pct.tbl
		ppt.tbl
		jva.tbl
 
	### 'c' program ('kixmqtst') for loading the MQSeries queue ###
	---------------------------------------------------------------
		kixmqerr.c
		kixmqerr.h
		kixmqtst.c
 
	### Data to be loaded by 'kixmqtst' ###
	---------------------------------------
		MQJMSAppl_GetAlias.data
 
	### MQSeries configuation command file ###
	------------------------------------------
		kixmqtst.mqconfig
 
	### Comm Mgr resource to define and enable trigger queue ###
	------------------------------------------------------------
		unikixrc.cfg
 
	### makefile for re-building and/or modifying the sample application ###
	-----------------------------------------------------------------------
		makefile
 
Files in $UNIKIX/test/mq/jms/kix_java
--------------------------------------
	### properties and classpath and librarypath files ###
	---------------------------------------
		MQJMS.properties
		Classpath.appends
		Libpath.appends
 
Requirements
------------
  MQSeries Client must be available on the same machine running MTP.
 
  MQSeries Server must be available on a host that is accessible to the MTP 
  host via TCP communication.  This example assumes that MTP and MQSeries 
  Server are running on the same host.  If this is not the case, then the 
  kixmqtst program must be compiled on the host that is running MQSeries Server.
  Copy the C source files and the data file MQJMSAppl_GetAlias.data to the
  host running MQSeries server and build according to compiler and MQSeries
  specifications for that host.
 
  This example requires JDK 1.3 (or later).
 
Procedure
---------
 
MQSeries Setup
---------------
Perform these commands on the MQSeries Server host machine.
 
1.   Run the crtmqm command to create an MQSeries queue manager named TESTQM.
       crtmqm -lf64 -q TESTQM
 
2.   Start the TESTQM queue manager using the 'strmqm' command.
       strmqm TESTQM
 
3.   Put the sample configuration into the queue manager using the runmqsc 
     command.
       runmqsc TESTQM < kixmqtst.mqconfig
 
     The kixmqtst.mqconfig file is in the $UNIKIX/test/mq/cobol directory.  It 
     contains definitions of the Queues, Procedures and Channel used by the 
     test application. If you are running MQSeries Server on a different host
     that your MTP region, you will need to copy this file to that host.
 
4.   Load the MQSeries input queue with message data from the
     MQJMSAppl_GetAlias.data file:
       kixmqtst -m TESTQM -q UNIKIXMQ1 -i MQJMSAppl_GetAlias.data
 
     This will cause both the data to be loaded on the input queue and
     a trigger message to be placed on the trigger queue.
 
MTP Setup
---------
1.   In addition to the required environment setup for running an MTP region,
     add (or verify the existance of) the following environment variables
 
	UNIKIX            Sun MTP's home directory
	KIXSYS            $UNIKIX/test/mq/jms
	KIXPROGS          $KIXSYS
	KIXMAPS           $KIXSYS
	KIXDATA           $KIXSYS
	KIXLIB            $KIXSYS
	KIXLICDIR         Sun MTP license file directory
 
	MQDIR             Install path for MQSeries (i.e., /opt/mqm)
	MQSERIES          Path to the MQSeries Java libraries 
                         (i.e., $MQDIR/java/lib)
	MQSERVER          CHANNEL1/TCP/hostname
                            where hostname is the name or IP address of the
                            host running MQSeries Server.  If the host is the
                            same as the host running MTP, the value is
                            localhost, otherwise specify the appropriate name
                            or IP address.
	JDKROOT           JDK home directory
	KIX_JVM_OPTIONS   "-XX:+AllowUserSignalHandlers -Xint"
	COBDIR            The install path of COBOL (i.e., /opt/cobol/1.1)
	COBCPY            $UNIKIX/copy
 
	LD_LIBRARY_PATH   Include the following:
                         $UNIKIX/bin
                         $JDKROOT/bin
                         $JDKROOT/lib
                         $JDKROOT/jre/lib/sparc
                         $JDKROOT/lib/sparc/classic:
                         $JDKROOT/jre/lib/sparc/native_threads
                         $MQSERIES
                         $MQDIR/lib
	PATH              Include the following:
                         $UNIKIX/bin
                         $COBDIR/bin
                         $JDKROOT/bin
                         <C compiler bin directory>
                         $MQDIR/bin
 
2.   If not already done, build the Transaction Processor so that it can 
     call MQSeries functions.  This is done using the 'kixinstall' program.
 
3.   Run make in the $UNIKIX/test/mq/jms directory to build the example.
     Note: on UNIX platforms you will have to uncomment the platform
     specific lines in the makefile.
 
4.   Ensure the following lines are in your $KIXSYS/unikixrc.cfg file:
     (If you don't have a unikixrc.cfg file copy the unikixrc file from
     $UNIKIX/lib and rename it unikixrc.cfg)
 
          MQServer*Active:            True
          MQServer*QueueManagerName:  "TESTQM"
          MQServer*QueueName:         "UNIKIX.TRIGGER.QUEUE"
 
5.   Edit the $KIXSYS/kix_java/Classpath.appends file.  Uncomment the following
     lines:
       /opt/mqm/java/lib/com.ibm.mqjms.jar
       /opt/mqm/java/lib/com.ibm.mq.jar
       /opt/mqm/java/lib/jms.jar
       /opt/mqm/java/lib/jndi.jar
 
     On each of the lines above, verify the path to the stated jar file, and
     change each accordingly (i.e., change /opt/mqm to the actual install path
     on your system for MQSeries Client).
 
6.   Edit the $KIXSYS/kix_java/Libpath.appends file. At the end of the file,
     add the following line:
       <mq dir>/java/lib
 
     where <mq dir> is the installation path of MQSeries on your system.
     Note: this path is identical to the value set in the MQSERIES environment 
     variable as stated in step 1 of the MTP Setup procedures, above.
 
7.   Edit the $KIXSYS/kix_java/MQJMS.properties file. Verify that the value
     for host is equal to the host name running MQSeries Server. If MQSeries
     Server is running on the same host as MTP, the default value of localhost
     will be sufficient.
	Note:  If you wish to run the more complex example, 
	       GetAliasJMSListenerExMQJMS, find the following lines in the
	       MQJMS.properties file:
	           PROG2 = scouser.GetAliasJMSListener
	           #PROG2 = scouser.GetAliasJMSListenerExMQJMS
	       edit the lines so that the GetAliasJMSListener line is commented,
	       and the GetAliasJMSListenerExMQJMS line is uncommented, i.e.:
	           #PROG2 = scouser.GetAliasJMSListener
	           PROG2 = scouser.GetAliasJMSListenerExMQJMS
	       If you want to change from one program to the other, you will need
	       to restart MTP after editing the MQJMS.properties file.
 
	See the comments in the MQJMS.properties sample file for further details.
 
8.   Start Sun MTP using kixstart. The 'unikixqm' daemon process will monitor 
     the queue UNIKIX.TRIGGER.QUEUE. The trigger monitor will start the MQJV
     transaction as a result of the trigger message waiting from the MQSeries 
     Setup step 4 (above).
 
9.   The transaction MQJV will put the data read from the queue and start the
     appropriate JMS application based on the configuration setup in the
     MQJMS.properties file (see step 7). Check the results of the sample
     application:
 
	GetAliasJMSListener : look in the file $KIXSYS/unikixmain.log for
                             the name and alias output messages.
	GetAliasJMSListenerExMQJMS : use the MQSeries utility 'amqsgbrc'
                                    to browse the output queue.
                                    amqsgbrc UNIKIXMQ2
 
 Expected Output: The following data is defined for the two GetAlias
                  applications:
	Name                       Alias
	-------------------------- -------------------------------
	George Herman Ruth         The BABE
	Frank Sinatra              Old Blue Eyes
	Daffy Duck                 A Fine Feathered Friend
	Davey Jones                Soggy Sailor
	Humpty Dumpty Smith        Crazy Egghead
	Kemo Sabe                  The Lone Ranger
	Clark Kent                 Superman
	Don Diego de la Vega       Zorro
	Elfego Baca                The Dude with Nine Lives
	Randy Johnson              The Big Unit
	Sugar Daddy                Uncle Sam
 
	You can alter the MQJMSAppl_GetAlias.data file and add names, one
	per line. If the name added is equal to a name in the 'Name' field
	above, then the resulting output will contain the corresponding
	'Alias'. If the name is not on the list, then the output will appear
	as "Couldn't match name." Note: names are case sensitive.
 
___________________________________________________________________________
	The comments below this line do not strictly apply to the
	Sample Application. But if the user modifies things in order to
	run it across multiple platforms the following items may prove
	helpful!
 
	********************************************************************
	If you are running the MQSeries QueueManager on one platform
	and the Sun MTP region with a JMS application as a client on
	another platform.
	********************************************************************
 
	*** Item #1 ***   ####################################
 
	java.lang.UnsatisfiedLinkError: /opt/mqm/java/lib/libmqjbnd02.so:
	     ld.so.1: unikixtran: fatal: libmqm.so: open failed:
	        No such file or directory
 
	On the client side something like the above error message
	may show up in the unikixmain.err log file along with a sizeable
	Java trace. It usually means that the 'host=' argument in the
	MQJMS.properties file s set to 'localhost' when it should have the
	hostname of the server platform where the MQSeries QueueManager
	is running.
 
	Edit the MQJMS.properties file and re-try.
 
	*** Item #2 ***   ####################################
 
	Another rather common client side problem is the
	following message in unikixmain.err:
 
	07/10/2001 15:39:31 unikixqm    :KIX3001E MQCONN() Error 2  Reason 2035
 
	This error message is the result of an MQSeries Client attempting a connect
	to the QueueManager without proper authorization. See the IBM MQSeries
	documentation for the meaning of the 'Reason code'.
 
	The simplest way around this error as far as the Sample Application is
	concerned is to:
 
	1) on the QueueManager server set the MCAUSER(...) argument
	   on the DEFINE CHANNEL command in the kixmqtst.mqconfig file
	   equal to the server's logon-id name and re-start the MQSeries
	   Queue manager.
 
	As an example      MCAUSER('MQserv_logon_ID')
 
	and
 
	2) on the MQSeries client platform define the MQ_USER_ID
          environment variable in the Sun MTP region to equal the same
          logon-id as #1 above.
 
	As an example       export MQ_USER_ID=MQserv_logon_ID
 
	Then re-cycle the Sun MTP region.
See IBM's MQ documentation for all the subtle particulars
on the above 2 steps.
 


Using JMS and COBOL Applications

The MQ-JMS Bridge works only with JMS Java applications. However, COBOL or other applications can exist in the same application space, placing messages on the queue or removing them. The common point of reference is the MQSeries trigger queue itself.

One version of the JMS sample application in the $UNIKIX/test/mq/jms directory places the output on an MQSeries queue named UNIKIXMQ2. Using that as an input queue, a triggered COBOL application can process the data from UNIKIXMQ2.


procedure icon  To Use the MQ-JMS Bridge to Trigger a COBOL Program

1. Make the changes shown in CODE EXAMPLE 13-4 to the MQSeries configuration file (kixmqtst.mqconfig) to define the UNIKIXMQ2 queue.

These changes tell the MQSeries service that if a message is placed on UNIKIXMQ2, a trigger message is to be created, and the triggered process is the KMQ2 transaction.

CODE EXAMPLE 13-4 UNIKIXMQ2 Trigger Configuration
* Declare a trigger queue and process for UNIKIXMQ2
INITQ(UNIKIX.TRIGGER.QUEUE)                     +
TRIGGER                                         +
TRIGDATA('Trig data from UNIKIXMQ2')            +
TRIGTYPE(FIRST)                                 +
PROCESS(KMQ2.TRIGGER.PROC)
 
DEFINE PROCESS('KMQ2.TRIGGER.PROC')  REPLACE    +
	DESCR('Invoke KMQ2 transaction')         +
	ENVRDATA('Some environment for KQM2')    +
	USERDATA('Some data for KQM2')           +
	APPLTYPE(CICS)                           +
	APPLCID('KMQ2')

2. Put the configuration into the queue manager by using the runmqsc command on the MQ Server. For example:

$ runmqsc TESTMQ < config-file

where TESTMQ is the queue manager name and config-file is the name of the configuration file.

3. In the PCT, add the COBOL program KIXMQ01 and associate the transaction ID KMQ2 with it.

4. In the PPT, add the COBOL program KIXMQ01.

5. Copy the COBOL program KIXMQ01.cl2 from $UNIKIX/test/mq/cobol to $UNIKIX/test/mq/jms.

6. Edit the makefile in the $UNIKIX/test/mq/jms directory to include the translation and compilation of the COBOL program.

See the makefile in the $UNIKIX/test/mq/cobol directory for an example. Re-make the entire application.

7. Start the region and run the sample application as before.

You can use the CEBR transaction to view the temporary storage queue MQTEST01. The output that used to be on UNIKIXMQ2 is now on the MQTEST01 queue.