|
home /
infca /
mq / mq_java
(navigation links)
|
That Christmas spirit is not what you drink
|
JMS - accés a MQ des Java
Concept
JMS is an API for asynchronous,
transacted message production, distribution, and delivery.
The Java Message Service (JMS) API is a Java Message Oriented Middleware (MOM) API for sending messages between two or more clients.
JMS is a standard that specifies how Java application send and receive messages -
whilst it offers portability, JMS does not guarantee interoperability
url
The JMS API is an API for accessing enterprise messaging systems from Java programs.
URL,
wiki, "JMS 1.1 FR spec.pdf"
The Java EE programming environment provides a standard API called JMS (Java Message Service),
which is implemented by most MOM vendors and aims to hide the particular MOM API implementations;
however, JMS does not define the format of the messages that are exchanged, so JMS systems are not interoperable.
MOM wiki
Unlike JMS, which merely defines an API, AMQP is a wire-level protocol.
A wire-level protocol is a description of the format of the data that is sent across the network as a stream of octets.
Consequently any tool that can create and interpret messages that conform to this data format
can interoperate with any other compliant tool irrespective of implementation language.
Note that, like HTTP and XMPP, AMQP does not have a standard API.
AMQP
Q & A
Q: What is the Java Message Service?
A: The Java Message Service (JMS) API is an API for accessing enterprise messaging systems.
It is part of the Java 2 Platform, Enterprise Edition (J2EE).
Q: Where can I find the Java Message Service specification?
A: The Java Message Service specification is available at
http://java.sun.com/products/jms/docs.html.
A link to the online JMS API documentation is at the same location.
JMS FAQ,
EE 1.3.1 Overview.
Messaging Systems and the Java Message Service (JMS), by
Sun
Q: What is JNDI ?
A: "Java Naming and Directory Interface" is a Java API for a directory service
that allows Java software clients to discover and look up data and objects via a name.
wiki
JMS and WAS
If you connect directly to MQ,
you simply use the WAS admin interfaces to configure the JMS resources offered by MQ JMS provider,
which are typically
- JMS Connection Factory
- JMS queue / JMS topic
- JMS Activation Specification
If you connect indirectly to MQ,
WAS is configured to use the default messaging provider to connect the application to the SIBus,
which in turn is configured to connect to MQ.
Advantatges ? If MQ is remote, you can work while remote MQ is not available.
Wallis - comparacio, bons links, etc
Modes d'accés a MQ des Java
TMM06 - Java APIs for WebSphere MQ :
- MQ Classes for JMS
- Provider-independence and standards
- Easy publish/subscribe
- Administrative configuration via JNDI
- Message selection
- Integration with J2EE Application Servers
- MQ Classes for Java
- Object oriented form of MQI
- Full access to MQ capabilities
- JMS has a few restrictions, such as no support for distribution lists
- MQ Base Classes for Java - de IBM
- JMS - de Sun
Les classes de IBM son directes i senzilles.
Les classes de JMS
(complicades i enfarragoses de manegar)
se suposa que son transportables i interoperables,
però en realitat no ho son pas.
WebSphere MQ classes for Java ('Base Java' - package com.ibm.mq)
or
WebSphere MQ classes for JMS (package com.ibm.mq.jms)
Definició classes MQ : import com.ibm.mq.* ;
Conexió al gestor : objetoQMgr = new MQQueueManager( "Nombre_Qmgr" ) ;
Obrir una cua :
MQQueue Cola_MQ = qMgr.accessQueue ( "Nombre_cola_MQ", openOptions ) ;
Definició classes JMS : import javax.jms.* ;
| Operació | Java | JMS
|
| Declaració | import com.ibm.mq.* ;
| import javax.jms.* ;
|
| MQCONN(qmgr) | qMgr = new MQQueueManager ( "QueueManagerName" ) ;
| qcf = ( QueueConnectionFactory ) ctx.lookup ( "jndiQCF" ) ;
|
| MQOPEN(queue) | MQQueue Cola_MQ = qMgr.accessQueue ( "QueueName", openOptions ) ;
|
El JMS és una especificació de l'interface i sempre necessita un "provider" de l'implementació (en aquest cas el MQ).
Els programes java inclouen crides a funcions JMS i el provider les tradueix al MOM.
Cada "provider" proporciona les seves "llibreries" de JMS.
Sun proporciona la especificació que és un estàndar (en java es diu el "interface", en aquest cas javax.jms).
Per proporcionar un JMS Provider has de tenir un producte capa d'enviar missatges asncronament.
Si no el tens, no pots implementar l'interface.
WebSphere MQ Classes for Java Message Service (WebSphere MQ Classes for JMS) es el proveedor JMS que se suministra con WebSphere MQ.
Además de implementar las interfaces que están definidas en el paquete javax.jms,...
Per altre banda, el que tu dius :
pots cridar directament al MQ des de java amb una API que no deixa de ser la versió Java del MQI.
Aquesta és a la que es refereixen com "MQ Classes for Java".
WebSphere MQ classes for Java encapsulate the Message Queue Interface (MQI), the native WebSphere MQ API.
MQ base Java versus MQ JMS
import com.ibm.mq.* ; ===>>> IMB MQ classes for Java - MQ Java API: com.ibm.mq.jar
import com.ibm.mq.jms.* ; ===>>> IBM clases for JMS - MQ JMS API: com.ibm.mqjms.jar (old?)
import javax.jms.* ; ===>>> Sun clases para JMS
Stuff in com.ibm.mq.jms packages are the IBM supplied implementation of the JMS Provider.
Stuff in javax.jms package are the Sun supplied implementation of the "client" side of the JMS API.
Stuff in com.ibm.mq package are the IBM supplied WebSphere MQ API for Java - which is not JMS at all.
JMS i JNDI
El JNDI es el contenedor de objetos abstractos.
Es el interface para acceder al servicio de nombres,
que proporciona
- almacena nombre y propiedades
- busqueda de nombre y devuelve sus propiedades
El JNDI almacena
- Connection Factory(s) : queue managers
- Destination(s) : cola/tema
El destino de un mensaje puede ser una cola o un tópico (publicación).
Defining which connection to use : Bindings/Client
The type of connection to use is determined by the setting of variables in the MQEnvironment class.
Two variables are used:
JMS Administration tool,
v7;
which connection to use.
7.5
// Set up MQSeries environment
MQEnvironment.hostname = "hostname" ;
MQEnvironment.channel = "channel_name" ;
MQEnvironment.properties.put ( MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES ) ; // Connection type
Binding connections
Complete .Net
sample.
Converted to Java : \\MQ\Java\MQsample_binding\
Client connections
For an application to connect to a queue manager in client mode, the application must specify the channel name, host name, and port number.
You can specify the channel name, host name, and port number in one of two ways:
either as fields in the MQEnvironment class
or as properties of the MQQueueManager object
If you set fields in the MQEnvironment class, they apply to your whole application, except where they are overridden by a properties hash table.
To specify the channel name and host name in MQEnvironment, use the following code:
MQEnvironment.hostname = "host.domain.com" ;
MQEnvironment.channel = "java.client.channel" ;
MQEnvironment.port = nnnn ;
publib
Java client connections differences
When WebSphere MQ classes for Java is used as a client,
it is similar to the WebSphere MQ C client,
but has a number of differences.
If you are programming for WebSphere MQ classes for Java for use as a client,
be aware of the following differences:
- it supports only TCP/IP.
- it does not read any WebSphere MQ environment variables at startup.
- information that would be stored in a channel definition and in environment variables is stored in a class called Environment. Alternatively, this information can be passed as parameters when the connection is made.
- error and exception conditions are written to a log specified in the MQException class. The default error destination is the Java console.
- it accesses client configuration information from an WebSphere MQ client configuration file rather than a qm.ini file. Values in qm.ini have no effect.
When used in client mode, WebSphere MQ classes for Java does not support the MQBEGIN call.
url
Using a client channel definition table (MQ v7)
As an alternative to creating a client connection channel definition
by setting certain properties of a ConnectionFactory object,
a WebSphere MQ classes for JMS application can use client connection channel definitions
that are stored in a client channel definition table.
These definitions are created by WebSphere MQ Script (MQSC) commands
or WebSphere MQ Programmable Command Format (PCF) commands.
When the application creates a Connection object,
WebSphere MQ classes for JMS searches the client channel definition table
for a suitable client connection channel definition,
and uses the channel definition to start an MQI channel.
To use a client channel definition table,
the CCDTURL property of a ConnectionFactory object must be set to a URL object.
The URL object encapsulates a uniform resource locator (URL)
that identifies the name and location of the file containing the client channel definition table
and specifies how the file can be accessed.
You can set the CCDTURL property by using the WebSphere MQ JMS administration tool,
or an application can set the property by creating a URL object
and calling the setCCDTURL() method of the ConnectionFactory object.
url
CCDT links
-
Using a Client Channel Definition Table (CCDT) in WebSphere MQ for Queue Manager Groups -
url
-
Using a CCDT file to connect to multiple WebSphere MQ queue managers using JMS -
url
-
Using a client channel definition table with IBM MQ classes for JMS -
url
CCDT working code
Ho ha fet possible en Esteve - gracies !
{pend} JMS ha de fer servir una cua dinamica per rebre la resposta del SAP
public class SenderPlainJMSnoJNDI {
// System exit status value
private static int my_status = 1; // set default (ok) value
// Variables
private static MQQueueConnectionFactory cf = null ;
private static MQQueueConnection my_MQ_SndQueue_connection = null ;
private static MQQueueSession my_MQ_SndQueue_session = null ;
private static MQQueue my_MQ_SndQueue = null ;
private static MQQueueSender my_MQ_sender = null ;
private static MQQueueConnection my_MQ_RcvQueue_connection = null ;
private static MQQueueSession my_MQ_RcvQueue_session = null ;
private static MQQueue my_MQ_RcvQueue = null ;
private static MQQueueReceiver my_MQ_receiver = null ;
private static Integer MENSAJES_A_ENVIAR = 10 ;
// private static Integer THINTIME_ENTRE_CADA_ENVIO_MENSAJE = 3000 ; // mili-seg
private static Integer mensajesenviados = 0 ;
private static Integer mensajespendientes = 0 ;
public static void main( String[] args ) throws JMSException {
System.out.println( "+++ JMS Server, v 20140116.1.1.a - Esteve i Sebastia" ) ;
System.out.println( "Nombre de missatges a enviar: " + MENSAJES_A_ENVIAR);
// System.out.println( "Temps d'espera entre missatges: " + THINTIME_ENTRE_CADA_ENVIO_MENSAJE/1000 + " segons");
mensajespendientes = MENSAJES_A_ENVIAR ;
construir_Objetos() ;
enviar_i_rebre_Missatges() ;
destruir_Objectes() ;
System.out.println( "--- JMS Server, v 1.0, 20131221.a - Esteve i Sebastia" ) ;
} ; // main()
private static void construir_Objetos() throws JMSException {
String szTAB = "C:/sebas/MQ/Eines/CCDT_test/ESTEVE.TAB" ;
String szNomCuaEntrada = "ENTRADA" ;
String szNomCuaResposta = "RESPOSTA" ;
System.out.println( ">>> construir_Objectes()" ) ;
try {
// Creacion Connection Factory = conexio al gestor
cf = new MQQueueConnectionFactory() ;
// Conexio a la CCDT
java.net.URL chanTab1 = new URL( "file:///"+ szTAB ) ; // http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.dev.doc/q032510_.htm
cf.setCCDTURL( chanTab1 ) ;
// Fijamos propiedades de la conexion
// La conexion debe ser balanceada a los gestores, debe especificarse un espacio en blanco
cf.setStringProperty( WMQConstants.WMQ_QUEUE_MANAGER, " " ) ;
// La conexion debe ser de tipo cliente
cf.setIntProperty( WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT );
// Debe indicarse los parametros de reconexion
cf.setIntProperty( WMQConstants.WMQ_CLIENT_RECONNECT_OPTIONS, WMQConstants.WMQ_CLIENT_RECONNECT ) ;
cf.setClientReconnectOptions( WMQConstants.WMQ_CLIENT_RECONNECT ) ;
// Creacion de la conexion a partir de la ConnectionFactory
my_MQ_SndQueue_connection = (MQQueueConnection) cf.createQueueConnection() ;
// Creacion de la Session a partir de la Connection
my_MQ_SndQueue_session = (MQQueueSession) my_MQ_SndQueue_connection.createQueueSession( false, Session.AUTO_ACKNOWLEDGE ) ;
// my_MQ_SndQueue_session = (MQQueueSession) my_MQ_SndQueue_connection.createSession( false, Session.AUTO_ACKNOWLEDGE ) ;
// Establim la cua destinataria del mensaje
my_MQ_SndQueue = (MQQueue) my_MQ_SndQueue_session.createQueue( "queue:///" + szNomCuaEntrada ) ;
System.out.println( "Enviem a la cua [" + szNomCuaEntrada + "]." ) ;
// Creacion del enviador de mensajes a partir de la Session
my_MQ_sender = (MQQueueSender) my_MQ_SndQueue_session.createSender( my_MQ_SndQueue ) ;
my_MQ_sender.setTimeToLive( 30000 ) ; // try to set MD.Expiry ;
my_MQ_sender.setPriority( 5 ) ; // app has to select the Priority too
my_MQ_RcvQueue_connection = (MQQueueConnection) cf.createQueueConnection();
// Creacion de la Session a partir de la Connection
my_MQ_RcvQueue_session = (MQQueueSession) my_MQ_RcvQueue_connection.createQueueSession( false, Session.AUTO_ACKNOWLEDGE ) ;
// Creamos la sesion a la cola destino donde deberian llegar las respuestas
my_MQ_RcvQueue = (MQQueue) my_MQ_RcvQueue_session.createQueue( "queue:///" + szNomCuaResposta ) ;
System.out.println( "Rebem a la cua [" + szNomCuaResposta + "]." ) ;
// create a receiver from session
my_MQ_receiver = (MQQueueReceiver) my_MQ_RcvQueue_session.createReceiver( my_MQ_RcvQueue ) ;
my_MQ_SndQueue_connection.start() ; //
my_MQ_RcvQueue_connection.start() ; //
// System.out.println( "Conectado al gestor:" + cf.getQueueManager() ) ;
} catch ( MalformedURLException eurl ) {
recordFailure( eurl );
eurl.printStackTrace();
} catch ( JMSException ejms ) {
recordFailure( ejms );
ejms.printStackTrace();
}
} ; // construir_Objetos()
private static void enviar_i_rebre_Missatges() throws JMSException {
int iRcvTimeout = 2000 ; // time to wait for a response message
System.out.println( ">>> enviar_i_rebre_Missatges()" ) ;
while ( mensajespendientes > 0 ) {
System.out.println( ">>> Lets send a message." ) ;
String t = "payload del missatge que enviem.";
try {
mensajespendientes-- ;
mensajesenviados++ ;
String t2 = String.format( "(%4.4s) " + t, mensajesenviados ) ;
JMSTextMessage message = (JMSTextMessage) my_MQ_SndQueue_session.createTextMessage( t2 ) ; // set text into message
message.setJMSReplyTo( my_MQ_RcvQueue ) ; // posem al missatge el nom de la cua on volem la resposta. el nom del gestor s'omple sol
message.setJMSType( "MQSTR " ) ; //
message.setJMSExpiration( 3 ) ; // dont let messages live forever - no va
message.setJMSPriority( 6 ) ; // verify we can see it on the other end - no va
my_MQ_sender.send( message ) ; // enviem el missatge
String myJMS_msgId = message.getJMSMessageID() ;
System.out.println( "sent msg ID [" + myJMS_msgId + "]" ) ;
Destination myJMS_ReplyTo = message.getJMSReplyTo() ;
System.out.println( "sent ReplyTo() [" + myJMS_ReplyTo + "]" ) ;
System.out.println( "sent body [" + t2 + "]" ) ;
String resultado = String.format( "+++ s'han enviat (%s) msgs i queden (%s) per enviar", mensajesenviados, mensajespendientes);
System.out.println( resultado ) ;
// Thread.sleep( THINTIME_ENTRE_CADA_ENVIO_MENSAJE ) ; // paramos unos instantes
} catch ( JMSException ejms ) {
recordFailure( ejms );
ejms.printStackTrace();
// } catch ( InterruptedException eint ) { // from sleep()
// eint.printStackTrace(); // from sleep()
} ; // try
// Recepcio de respostes
try {
String szOut = String.format( ">>> Lets wait (%d) mili-secs for a response.", iRcvTimeout ) ;
System.out.println( szOut ) ;
Message receivedMessage = my_MQ_receiver.receive( iRcvTimeout ) ; // esperem resposta una estoneta
if ( receivedMessage != null ) {
System.out.println( "Received message:\n" + receivedMessage ) ;
Destination myJMS_ReplyTo = receivedMessage.getJMSReplyTo() ;
System.out.println( "rcvd ReplyTo() [" + myJMS_ReplyTo + "]." ) ;
if ( receivedMessage instanceof TextMessage ) {
replyString = ((TextMessage) receivedMessage).getText();
// System.out.println( "\nReceived message:\n" + replyString ); --- es veu FATAL
} else {
// Print error message if Message was not a TextMessage.
System.out.println( "--- Reply message was not a TextMessage" ) ;
} ;
} else {
System.out.println( "--- no msg received." ) ;
}
} catch ( JMSException ejms ) {
recordFailure( ejms );
ejms.printStackTrace();
}
} ; // while
} ; // enviar_i_rebre_Missatges()
private static void destruir_Objectes() throws JMSException {
System.out.println( ">>> destruir_Objectes()" ) ;
try {
my_MQ_SndQueue_session.close() ;
my_MQ_SndQueue_session = null ;
if ( my_MQ_SndQueue_connection != null) {
my_MQ_SndQueue_connection.stop() ;
my_MQ_SndQueue_connection.close() ;
my_MQ_SndQueue_connection = null ;
}
my_MQ_RcvQueue_session.close() ;
my_MQ_RcvQueue_session = null ;
if ( my_MQ_RcvQueue_connection != null) {
my_MQ_RcvQueue_connection.stop() ;
my_MQ_RcvQueue_connection.close() ;
my_MQ_RcvQueue_connection = null ;
}
my_MQ_SndQueue = null ;
my_MQ_sender = null ;
my_MQ_RcvQueue = null ;
my_MQ_receiver = null ;
cf = null ;
} finally {
} ;
} ; // destruir_Objectes() ;
// end main()
/**
* Record this run as failure.
*
* @param ex
* @throws JMSException
*/
private static void recordFailure( Exception ex ) throws JMSException {
if ( ex != null ) {
if ( ex instanceof JMSException ) {
processJMSException( (JMSException) ex );
} else {
System.out.println( ex );
}
}
System.out.println("--- RUN FAILURE ***");
my_status = -1;
return;
} ; // recordFailure
/**
* Process a JMSException and any associated inner exceptions.
*
* @param jmsex
* @throws JMSException
*/
private static void processJMSException( JMSException jmsex ) throws JMSException {
System.out.println( jmsex );
Throwable innerException = jmsex.getLinkedException();
if ( innerException != null ) {
System.out.println( "Inner exception(s):" ) ;
}
while ( innerException != null ) {
System.out.println( innerException ) ;
innerException = innerException.getCause() ;
}
System.out.println( "S'ha produit un tall a la comunicacio - reconectem." ) ;
construir_Objetos();
enviar_i_rebre_Missatges();
destruir_Objectes() ;
return;
} ; // processJMSException
} ; // public class
Accessing JMS from an Applet
sample - also \\MQ\Java\MQsample_applet\
JMS using dymanic response queues
T.Rob says : 1000 dynamic queues with one message each may actually be faster than a single queue with 1000 threads getting by CORRELID
destination = session.createQueue( "queue:///Q1" ) ;
producer = session.createProducer( destination ) ;
tempDestination = session.createTemporaryQueue() ;
consumer = session.createConsumer( tempDestination ) ;
long uniqueNumber = System.currentTimeMillis() % 1000 ;
TextMessage message = session.createTextMessage("SimpleRequestor: Your lucky number today is " + uniqueNumber) ;
message.setJMSReplyTo( tempDestination ) ; // Set the JMSReplyTo
connection.start() ; // Start the connection
producer.send( message ) ; // And, send the request
System.out.println( "Sent message:\n" + message ) ;
// Now, receive the reply
Message receivedMessage = consumer.receive(15000) ; // in ms or 15 seconds
System.out.println( "\nReceived message:\n" + receivedMessage ) ;
url
JMS code samples
Lets run it
cd \\MQ\Java\Simplest\
set fn=SimplePTP
set fnj=%fn%.java
cd ABC
echo Compilar \\MQ\Java\Simplest\ABC\SimplePTP.java
javac %fnj%
cd ..
echo Ejecutar \\MQ\Java\Simplest\ABC\SimplePTP{.class}
java ABC.%fn%
Objectiu
Fer un Java MQCONNX amb
- MQEnvironment.userID := "mqm" ;
- MQEnvironment.password := "any" ;
or JMS code with
- cf.createConnection ( "mqm", "any" ) ;
code sample
{improve it with 2 more lines @ T42:\\Java\MQ\JMSDEMO.zip }
Connection factories are objects that enable JMS clients
to create JMS connections.
A connection factory supports concurrent use,
enabling multiple threads to access the object simultaneously.
After defining a JMS server,
you can configure one or more connection factories
to create connections with predefined attributes.
JMS working sample - client access
This code runs ok under XP, 20130330 !
Try W7 or W2008 server, 64-bit.
//
// ===========================================================================
// sample application : WebSphere MQ classes for Java
// code location : \\MQ\Java\MQsample\
// To compile this sample : javac MQSample.java
// To run this sample : java MQSample
// ===========================================================================
//
import com.ibm.mq.* ; // include WebSphere MQ classes for Java package
public class MQSample
{
private String qManager = "INDI" ; // define name of queue manager to connect to.
private String szQueueName = "QD1" ; // define queue to use
private MQQueueManager qMgr ; // define a queue manager object
public static void main ( string args[] ) {
new MQclientSample();
}
public MQclientSample() {
try {
MQEnvironment.hostname = "192.168.187.136" ; // host
MQEnvironment.port = 1466 ; // port
MQEnvironment.channel = "CH.JAVA.SVRCONN" ; // SVRCONN channel name
MQEnvironment.properties.put ( MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT ) ; // Connection type
MQEnvironment.userID = "sebastia" ;
MQEnvironment.password = "any" ;
// Create a connection to the queue manager
System.out.println ( "The Qmgr name is : " + qManager ) ;
qMgr = new MQQueueManager ( qManager ) ; // MQCONN()
// 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...
System.out.println ( "The Queue name is: " + szQueueName ) ;
MQQueue my_local_queue = qMgr.accessQueue ( szQueueName, openOptions ) ; // MQOPEN()
// Define a simple WebSphere MQ message, and write some text in UTF format..
MQMessage msg_hello_world = new MQMessage();
msg_hello_world.writeUTF ( "Hello World !" ) ;
// specify the message options...
MQPutMessageOptions pmo = new MQPutMessageOptions() ; // accept the defaults, same as MQPMO_DEFAULT
// put the message(s) on the queue
int iCnt = 0 ;
while ( iCnt < 1000 ) {
System.out.println ( iCnt + " - put() message." ) ;
my_local_queue.put ( msg_hello_world, pmo ) ; // MQPUT()
iCnt ++ ;
int j = 0 ;
while ( j < 10000000 ) { j ++ ; } ;
} ; // while loop
// get the message back again...
// First define a WebSphere MQ message buffer to receive the message into..
MQMessage retrievedMessage = new MQMessage() ;
retrievedMessage.messageId = msg_hello_world.messageId ; // set message id
// Set the get message options...
MQGetMessageOptions gmo = new MQGetMessageOptions() ; // accept the defaults same as MQGMO_DEFAULT
// get the message off the queue...
System.out.println ( "Get() message." ) ;
my_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 I have just got is : " + msgText ) ;
// Close the queue...
System.out.println ( "Close() queue." ) ;
my_local_queue.close() ;
// Disconnect from the queue manager
System.out.println ( "Disconnect() queue manager." ) ;
qMgr.disconnect() ;
}
// If an error has occurred in the above, try to identify what went wrong
catch ( MQException ex ) // was it a WebSphere MQ error?
{
System.out.println ( "--- A MQ error occurred : Completion code " + ex.completionCode + " Reason code " + ex.reasonCode ) ;
}
catch ( java.io.IOException ex ) // was it a Java buffer space error?
{
System.out.println ( "--- An error occurred whilst writing to the message buffer: " + ex ) ;
}
} // MQclientSample
} // class
JMS & HTML
Parts
- llegir dades de entrada des HTML
- cridar a la API de MQ
- escriure dades de sortida a HTML
Estructura
El codi java inclou un import com.ibm.mq.* ;
Ha de existir un com.ibm.mq.jar
De on es demana el jms.jar ? javax.jms.* ??
Lectura de les dades des HTML
Crida a la API de MQ des Java
Escriptura de les dades a HTML
JMS MQCONNX sample
import com.ibm.mq.* ; // include the WebSphere MQ classes for Java package
import java.io.* ;
public class MQPruebaConexion {
private String nombreMQ = "QMNAME" ; // Define e inicializa variable nombre MQ
private MQQueueManager objetoQMgr ; // Define un objeto MQ
public static void main(String args[]) {
new MQPruebaConexion() ;
}
public MQPruebaConexion() {
try {
// set IP, port, channel, user
MQEnvironment.hostname = "10.11.12.13" ;
MQEnvironment.port = 1420 ;
MQEnvironment.channel = "CH_2_HOST.M42F" ;
MQEnvironment.userID = "@USER1";
// pongo trace en mi fichero
FileOutputStream trace = new FileOutputStream( "MyTrace.txt" ) ;
MQEnvironment.enableTracing( 2, trace ) ;
// Crea una conexión con el gestor de colas
objetoQMgr = new MQQueueManager ( nombreMQ ) ; // MQCONN()
// Configurar las opciones en la cola que se va a abrir ... Todas las opciones de WebSphere MQ tienen el prefijo MQC en Java
int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT ;
// Especificar la cola que se va a abrir
MQQueue my_local_queue = objetoQMgr.accessQueue ( "QL.QTP.PRUEBAS", openOptions ) ; // MQOPEN()
// Definir un mensaje WebSphere MQ simple y escribir texto en formato UTF...
MQMessage mensaje = new MQMessage() ;
mensaje.writeUTF ( "Mensaje grabado desde Java en mi PC al MQ en zOS - M42F - " ) ;
// especificar las opciones de mensaje para escribir...
MQPutMessageOptions opcionesPut = new MQPutMessageOptions() ; // aceptar los valores por omisión, igual que MQPMO_DEFAULT
// escribir el mensaje a la cola
my_local_queue.put ( mensaje, opcionesPut ) ; // MQPUT()
// obtener de nuevo el mensaje ...
MQMessage retrievedMessage = new MQMessage() ;
retrievedMessage.messageId = mensaje.messageId ;
// Establecer las opciones de obtención de mensajes...
MQGetMessageOptions opcionesGet = new MQGetMessageOptions() ; // aceptar los valores por omisión, as MQGMO_DEFAULT
// extraer el mensaje de la cola...
my_local_queue.get( retrievedMessage, opcionesGet ) ; // MQGET()
// Y probar que tenemos el mensaje visualizando el texto de mensaje UTF
String msgText = retrievedMessage.readUTF() ;
System.out.println( "El mensaje es: " + msgText ) ;
// Cerrar la cola...
my_local_queue.close() ; // MQCLOSE()
// Desconectar del gestor de colas
objetoQMgr.disconnect() ; // MQDISC()
}
// Control de errores
catch ( MQException ex ) // ¿ era un error de WebSphere MQ ?
{
System.out.println ( "MQ error - CC " + ex.completionCode + ", RC " + ex.reasonCode ) ;
}
catch ( java.io.IOException ex ) // ¿ era un error de espacio de almacenamiento intermedio de Java ?
{
System.out.println ( "Se ha producido un error al grabar mensaje en almacenamiento intermedio de mensajes: " + ex ) ;
}
} // conexion
} // class
Object Model - MQclases para Java
Send
import com.ibm.mq.* ; // include the WebSphere MQ classes for Java package
public class MQSample extends java.applet.Applet
{
private String hostname = Direccion IP o nombre host gestor MQ ;
private String channel = Puerto TCP/IP listener gestor MQ ;
private String qManager = Nombre gestor MQ ;
private MQQueueManager qMgr ;
public void init()
{
MQEnvironment.hostname = hostname ;
MQEnvironment.channel = channel ;
MQEnvironment.properties.put ( MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT ) ; // select "client mode"
}
public void start()
{
try {
qMgr = new MQQueueManager ( qManager ) ; // MQCONN()
int openOptions = MQC.MQOO_OUTPUT ;
MQQueue Cola_MQ = qMgr.accessQueue ( "Nom_cua_MQ", openOptions ) ; // MQOPEN()
MQMessage MsgMQ = new MQMessage() ;
MsgMQ.writeByte ( "Datos_mensaje_MQ" ) ;
MQPutMessageOptions pmo = new MQPutMessageOptions() ;
Cola_MQ.put(MsgMQ,pmo) ; // MQPUT()
MsgMQ.close() ; // MQCOMMIT() ?
Cola_MQ.close() ; // MQCLOSE()
qMgr.disconnect() ; // MQDISC()
} // try
catch ( MQException ex ) {
System.out.println ( "Error MQ : CompCode " +
ex.completionCode + " ReasonCode " + ex.reasonCode ) ;
}
catch ( java.io.IOException ex ) {
System.out.println ( "Error en escritura buffer: " + ex ) ; }
}
} ; // start()
} ; // class
Receive
import com.ibm.mq.* ; // Include the WebSphere MQ classes for Java package
public class MQSample extends java.applet.Applet
{
private String hostname = Direccion IP o nombre host gestor MQ ;
private String channel = Puerto TCP/IP listener gestor MQ ;
private String qManager = Nombre gestor MQ ;
private MQQueueManager qMgr ;
public void init()
{
MQEnvironment.hostname = hostname ;
MQEnvironment.channel = channel ;
MQEnvironment.properties.put ( MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES ) ;
} ; // init
public void start()
{
try {
qMgr = new MQQueueManager ( qManager ) ;
int openOptions = MQC.MQOO_INPUT_SHARED ;
MQQueue Cola_MQ = qMgr.accessQueue ( "Nombre_cola_MQ", openOptions ) ;
MQMessage MsgMQ = new MQMessage() ;
MQGetMessageOptions gmo = new MQGetMessageOptions() ;
Cola_MQ.get ( MsgMQ, gmo ) ;
String msgText = MsgMQ.readUTF() ;
MsgMQ.close() ;
Cola_MQ.close() ;
qMgr.disconnect() ;
}
catch ( MQException ex ) {
System.out.println ( "Error MQ : CompCode " + ex.completionCode + " ReasonCode " + ex.reasonCode ) ;
}
catch ( java.io.IOException ex ) {
System.out.println("Error en lectura buffer: " + ex) ; }
}
} ; // start()
} ; // class
Send REQ + Receive RSP
import com.ibm.mq.* ; // Include the WebSphere MQ classes for Java package
public class MQSample extends java.applet.Applet
{
private String hostname = Direccion IP o nombre host gestor MQ ;
private String channel = Puerto TCP/IP listener gestor MQ ;
private String qManager = Nombre gestor MQ ;
private MQQueueManager qMgr ;
public void init()
{
MQEnvironment.hostname = hostname ;
MQEnvironment.channel = channel ;
MQEnvironment.properties.put ( MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES ) ;
}
public void start()
{
try {
qMgr = new MQQueueManager( qManager ) ;
int openOptions = MQC.MQOO_OUTPUT ;
MQQueue Cola_MQ_Req = qMgr.accessQueue ( "Nombre_cola_MQ_Request", openOptions ) ;
MQMessage MsgMQ_Req = new MQMessage() ;
MQMessage MsgMQ_Rep = new MQMessage() ;
MsgMQ_Req.writeUTF ( "Datos_mensaje_MQ" ) ;
MQPutMessageOptions pmo = new MQPutMessageOptions() ;
Cola_MQ_Req.put(MsgMQ_Req,pmo) ;
MsgMQ_Rep.correlationId = MsgMQ_Req.messageId ;
MsgMQ_Req.close() ;
Cola_MQ_Req.close() ;
openOptions = MQC.MQOO_INPUT_SHARED ;
MQQueue Cola_MQ_Rep = qMgr.accessQueue("Nombre_cola_MQ_Reply", openOptions) ;
MQGetMessageOptions gmo = new MQGetMessageOptions() ;
Cola_MQ_Rep.get ( MsgMQ_Rep, gmo ) ;
String msgText = MsgMQ_Rep.readUTF() ;
MsgMQ_Rep.close() ;
Cola_MQ_Rep.close() ;
qMgr.disconnect() ;
}
catch (MQException ex) {
System.out.println( "Error MQ : CompCode " + ex.completionCode + " ReasonCode " + ex.reasonCode) ; }
catch (java.io.IOException ex) {
System.out.println( "Error de escritura buffer: " + ex) ; }
}
} ; // start()
} ; // class
Receive REQ + Send RSP
Pending
url
req/rsp
JMS
Object Model - JMS
See
\\MQ\JMS\Stand_Alone_MQv6_JMSdemo\JMSDEMO\com\ibm\examples\JMSDemo.java
from
here.
Similar :
here
Includes complete JNDI configuration
- bindings mode transport: JMSAdmin.bat < jmsdemoJNDIbindings.scp
- client mode transport: JMSAdmin.bat < jmsdemoJNDIclient.scp
import javax.jms.* ;
import javax.naming.Context ;
import javax.naming.InitialContext ;
import javax.naming.NamingException ;
import com.ibm.mq.jms.* ;
import com.ibm.mq.MQC.* ;
public class PutMsg
{
static public void main ( String[] args )
{
Context ctx ;
QueueConnectionFactory qcf ;
QueueConnection con = null ;
Queue sendqueue ;
QueueSession session ;
QueueSender sender ;
TextMessage messagemq ;
try {
ctx = new InitialContext() ;
qcf = ( QueueConnectionFactory ) ctx.lookup ( "jndiQCF" ) ;
con = qcf.createQueueConnection() ;
session = con.createQueueSession ( false, Session.AUTO_ACKNOWLEDGE ) ;
sendqueue = ( Queue ) ctx.lookup ( "jndiQSend" ) ;
sender = session.createSender ( sendqueue ) ;
messagemq = session.createTextMessage ( "Datos mensaje" ) ;
sender.send ( sendqueue, messagemq ) ;
sender.close() ;
} catch ( JMSException je ) {
System.out.println ( "error " + je ) ;
Exception le = je.getLinkedException() ;
if (le != null) System.out.println ( "linked exception " + le ) ;
} catch ( NamingException ne ) {
System.out.println ( "error " + ne ) ;
} finally {
if ( con != null ) {
try {
con.close() ;
} catch (JMSException je) {
System.out.println ( "error " + je ) ;
Exception le = je.getLinkedException() ;
if (le != null) System.out.println ( "linked exception " + le ) ;
}
}
} // finally
} // main
} // class
import javax.jms.* ;
import javax.naming.Context ;
import javax.naming.InitialContext ;
import javax.naming.NamingException ;
import com.ibm.mq.jms.* ;
import com.ibm.mq.MQC.* ;
public class ReceiverMsg
{
static public void main ( String [] args )
{
Context ctx ;
QueueConnectionFactory qcf ;
QueueConnection con = null ;
Queue receiverqueue ;
QueueSession session ;
QueueReceiver receiver ;
Message messagemq ;
try {
ctx = new InitialContext() ;
qcf = ( QueueConnectionFactory ) ctx.lookup ( "jndiQCF" ) ;
con = qcf.createQueueConnection() ;
con.start() ;
session = con.createQueueSession ( false, Session.AUTO_ACKNOWLEDGE ) ;
receiverqueue = ( Queue ) ctx.lookup ( "jndiQReceiver" ) ;
receiver = session.createReceiver ( receiverqueue ) ;
messagemq = receiver.receive() ;
if ( messagemq == null ) {
System.out.println ( "ERROR: mensaje invalido" ) ;
}
receiver.close() ;
} catch ( JMSException je ) {
System.out.println ( "error " + je ) ;
Exception le = je.getLinkedException() ;
if (le != null) System.out.println ( "linked exception " + le ) ;
} catch ( NamingException ne ) {
System.out.println ( "error " + ne ) ;
} finally {
if ( con != null ) {
try {
con.close() ;
} catch ( JMSException je ) {
}
}
}
} // main
} // class
|
Send + Receive
|
Top
|
import javax.jms.* ;
import javax.naming.Context ;
import javax.naming.InitialContext ;
import javax.naming.NamingException ;
import com.ibm.mq.jms.* ;
import com.ibm.mq.MQC.* ;
public class PetResp
{
static public void main()
{
Context ctx ;
QueueConnectionFactory qcf ;
QueueConnection con = null ;
Queue sendqueue ;
Queue receivequeue ;
QueueSession session ;
QueueSender sender ;
QueueReceiver receiver ;
TextMessage messagemq ;
String messageID ;
Message messagercv ;
String filter ;
try {
ctx = new InitialContext() ;
qcf = ( QueueConnectionFactory ) ctx.lookup ( "jndiQCF" ) ;
con = qcf.createQueueConnection() ;
con.start() ;
session = con.createQueueSession ( false, Session.AUTO_ACKNOWLEDGE ) ;
sendqueue = ( Queue ) ctx.lookup ( "jndiQSend" ) ;
sender = session.createSender ( sendqueue ) ;
messagemq = session.createTextMessage ( "Datos mensaje" ) ;
sender.send ( sendqueue, messagemq ) ;
messageID = messagemq.getJMSMessageID() ;
sender.close() ;
filter = "JMSCorrelationID = '" + messageID + "'" ;
receivequeue = ( Queue ) ctx.lookup ( "jndiQRcv" ) ;
receiver = session.createReceiver ( receivequeue, filter ) ;
messagercv = receiver.receive ( 1000 ) ;
if ( messagercv == null ) {
System.out.println ( "ERROR: no message received" ) ;
}
else {
System.out.println ( "Datos mensaje respuesta: " + messagercv ) ;
}
receiver.close() ;
} catch ( JMSException je ) {
System.out.println ( "error " + je ) ;
Exception le = je.getLinkedException() ;
if (le != null) System.out.println ( "linked exception " + le ) ;
} catch ( NamingException ne ) {
System.out.println ( "error " + ne ) ;
} finally {
if ( con != null ) {
try {
con.close() ;
} catch ( JMSException je ) {
}
}
}
} // main
} // class
|
How to set UserID
|
Top
|
One way around it was to set the user ID and password when I created the queue connection.
When I subsequently created a message, the JMSXUserID property was properly set by MQ.
// Create a queue connection.
QueueConnection conn = qcf.createQueueConnection ( userID, password ) ;
Pointers
Volem fer un Connect, Open, Put, Get, Close, Disconnect.
- 2 Java 2 MQ from Korreus
- 1 Java 2 MQ from TEST.HTML
Samples
Have a look at <MQ>\tools\Java\base
and <MQ>\tools\Java\jms
{ MQ v7 : <MQ>\Tools\jms\samples\ }
JMS
-
Article en castellà : Introducción a JMS
-
Intro to JMS
-
Sun
JMS specs -
JMS specs
The Java Message Service (JMS) API is a messaging standard
that allows application components based on the Java 2 Platform,
Enterprise Edition (J2EE)
to create, send, receive, and read messages.
It enables distributed communication that is loosely coupled, reliable, and asynchronous.
-
JMS Administration tool : <MQ base dir>\Java\bin\ -
use JMSAdmin
see "Using Java", page 41 (59 of 539),
"Invoking the Administration tool"
-
WAS
intro to JMS !
-
Magnífic
techjournal :
sample tx & rx using JMS, MQ setup, WAS setup, etc
Arquitectura de JMS
Una aplicación JMS consta de los siguientes elementos:
-
Clientes JMS
Aplicaciones que envian o reciben mensajes a través de JMS
-
Mensajes
Los mensajes que se intercambian
-
Objetos administrados
Los objetos JMS a los que se dirigen las comunicaciones
Objetos administrados
Los objetos administrados son el punto al que se comunican los clientes JMS para enviar o recibir mensajes.
Se denominan objetos administrados
por que los crea el administrador
(en la implementación de referencia mediante j2eeadmin).
Implementan las interfaces JMS
y se sitúan en el espacio de nombres de JNDI
(Java Naming and Directory Interface)
para que los clientes puedan solicitarlos.
Hay dos tipos de objetos administrados en JMS:
- ConnectionFactory:
Se usa para crear una conexión al proveedor del sistema de mensajes.
-
Destination:
Son los destinos de los mensajes que se envían
y el recipiente de los mensajes que se reciben.
Mensajes
Es el corazn del sistema de mensajes.
Estan formados por tres elementos:
- Header: es la cabecera del mensaje, y contiene una serie de campos que le sirven a los clientes y proveedores a identificar a los mensajes.
- Properties: son propiedades personalizadas para un mensaje en particular.
- Body: es el mensaje en si.
Clientes JMS
Son clientes de JMS tanto el que suministra mensajes como el que los recibe.
Todos tienen una serie de pasos en comn antes de lograr enviar o recibir un mensaje:
- Conseguir un objeto ConnectionFactory a travs de JNDI.
- Conseguir un destino, mediante el objeto Destination a travs de JNDI.
- Usar ConnectionFactory para conseguir un objeto Connection
- Usar Destination para crear un objeto Session.
From
here
JNDI
The Java Naming and Directory Interface (JNDI) API implementation provides directory and naming functionality to programs developed in Java.
This allows Java programs to discover and retrieve objects of any type from the JNDI name space.
JMS has two types of administered objects:
- a ConnectionFactory
- a Destination
An administrator can place objects of these types in the JNDI name space
to be accessed by messaging applications.
So, how does an administrator put these objects in the JNDI name space?
This step is vendor specific.
If you are using WebSphere MQ V5.3 with WebSphere Application Server V5.0
you can administer these objects right from the WebSphere Administrative Console.
If you are using another application server,
WebSphere MQ V5.3 provides a tool called JMSAdmin for this purpose.
http://www.redbooks.ibm.com/redpieces/pdfs/sg246875.pdf
The Java Naming and Directory Interface (JNDI)
is an API for directory services.
It allows clients to discover and lookup data and objects via a name
and, like all Java APIs that interface with host systems,
is independent of the underlying implementation.
Additionally, it specifies a service provider interface (SPI)
that allows directory service implementations
to be plugged into the framework.
Wikipedia,
wiki.
JMSAdmin
The administration tool enables administrators
to define the properties of eight types of WebSphere MQ JMS object
and to store them within a JNDI namespace.
Then, JMS clients can use JNDI to retrieve these administered objects
from the namespace and use them.
The JMS objects that you can administer by using the tool are:
- MQConnectionFactory
- MQQueueConnectionFactory
- MQTopicConnectionFactory
- MQQueue
- MQTopic
- MQXAConnectionFactory
- MQXAQueueConnectionFactory
- MQXATopicConnectionFactory
URL
Remember as well if you try to run some of the JMS samples
that you will need to run JMSAdmin first
and create the relevant file Context before the sample will work.
Hint: create the context with type *FileContext first
(its the easiest to master)
and if that works well for you, you may graduate to other contexts.
Try with -nojndi option first and then start using JMSAdmin.
Look at the source code for the samples on how to use -nojndi ...
Iniciando Administración del Servicio de mensajes de WebSphere MQ Classes for Java(tm)
Inicializando el contexto JNDI...
INITIAL_CONTEXT_FACTORY: com.sun.jndi.fscontext.RefFSContextFactory
PROVIDER_URL: file:/C:/JNDI-Directory
La inicialización de JNDI ha fallado; por favor compruebe los valores de JNDI y el servicio.
Para obtener información adicional sobre la razón de este problema, ejecútelo con el argumento -v
Error: javax.naming.NameNotFoundException; remaining name 'C:\JNDI-Directory'
Error: javax.naming.NameNotFoundException; remaining name 'C:\Program Files\IBM\WebSphere MQ\Java\bin\sebasMQJNDI'
How to configure the JMSAdmin tool to work properly with the WebSphere 4.0 namespace
We run command
C:\Program Files\IBM\WebSphere MQ\Java\bin> jmsadmin < c:\sebas\MQ\JNDI\createJNDI.defs
File "C:\Program Files\IBM\WebSphere MQ\Java\bin\JMSAdmin.config" has :
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
PROVIDER_URL=file:/C:/sebas/MQ/JNDI
File \\MQ\JNDI\createJNDI.defs has :
# Define a QueueConnectionFactory
# Only parameters being overridden from their default values are specified.
# This sets up a MQ client binding.
DEF QCF(QCF) +
TRANSPORT(CLIENT) +
QMANAGER(JMSQM) +
HOSTNAME(localhost) +
PORT(1414)
# Define a Queue Destination
DEF Q(INPUTQ) +
QUEUE(INPUTQ) +
QMANAGER(JMSQM)+
#
DEF Q(OUTPUTQ) +
QUEUE(OUTPUTQ) +
QMANAGER(JMSQM)
#
END
Ara JMSADMIN dona
Iniciando Administración del Servicio de mensajes de WebSphere MQ Classes for Java(tm)
InitCtx>
JMS objects @ MQ Explorer
JMS administered objects are stored in Java Naming and Directory Interface (JNDI) namespaces.
In Initial context defines the root of a JNDI namespace
and is used to access the JMS objects that are stored in the namespace.
Where is the JNDI namespace located ?
- LDAP server
- file system
- other
MDB
MDB by Sun
JMS en EJB's: Message Driven Bean
La especificación 2.0 de EJB introdujo un nuevo tipo de Enterprise Java Bean, el Message Driven Bean.
Hasta ahora, para integrar una aplicación J2EE con JMS habia que programar un consumidor de mensajes
que hiciese llegar los mensajes que recibiese a un Session Bean, y que fuese éste el que los tratase.
Esta solución, aparte de añadir una capa mas, no era la mas correcta.
Con la inclusión del nuevo tipo de EJB, se consigue que la aplicación J2EE
sea capaz de recibir mensajes JMS y de tratarlos por sí misma, con los beneficios que esto conlleva:
seguridad, transacciones dentro del servidor de aplicaciones, etc...
Este nuevo tipo de beans se comporta como un bean de sesión sin estado.
Los MDB's (Message Driven Beans), al contrario que los otros tipos de EJB, no tienen implementar ninguna interfaz remota,
pues no van a ser utilizados desde fuera del servidor de aplicaciones, por lo que solo hace falta programar el Bean propiamente dicho.
Todos los MDB's implementan dos interfaces:
-
MessageDrivenBean, que nos obliga a sobreescribir los métodos ejbCreate(), ejbRemove() y setMessageDrivenContext()
-
MessageListener, teniendo que sobreescribir el método onMessage().
El enterprise bean se comporta de la misma manera que un cliente normal que recoja mensajes en el servicio JMS.
La diferencia es que no tendremos que preocuparnos de conseguir las interfaces de la JNDI,
pues de eso ya se encarga el servidor de aplicaciones
(nosostros le indicamos cual sera la factory y el asunto o la cola de la que debe recibir mensajes).
El archivo
MensajeBeanCola.java
contiene un MDB que consulta la cola que hemos estado usando hasta ahora
y si tiene mensajes, imprime su contenido en pantalla.
Puede observarse que solo se ha escrito codigo para el metodo onMessage().
From here :
Introducción a JMS (Java Message Service)
Code on WAS and RAD 8.5
package sebasPackage;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
/*
* Message-Driven Bean implementation class for: sebasClass
*
*/
@MessageDriven(
activationConfig = { @ActivationConfigProperty(
propertyName = "destinationType", propertyValue = "javax.jms.Queue"
) })
public class sebasClass implements MessageListener {
String kszID = "+++ sebasMDBClass v1.2" ;
public sebasClass() {
}
public void onMessage(Message message) {
System.out.printf( "%s - %s", kszID, "hola" ) ;
System.out.println( message.toString() );
System.out.println( String.format( "%s - %s", kszID, "ciao" ) ) ;
} ; // onMessage
} ; // class
short
complete
MQ access from Java
Point a web-browser containing a Java 1.3 runtime Plugin (as Netscape 6) to this page :
<MQ base directory>\Tools\Java\jms\applet\en_US\test.html
[T42] VM-BI:file://localhost/C:/TEMP/JavaJDK/test.html
T42:\MQ\Java\Test_Instalacio\test.html
It is an installation verification applet.
The applet connects to a given queue manager,
exercises all the WebSphere MQ calls,
and produces diagnostic messages if there are any failures
.
Using Java, csqzasw12.pdf, page 29 (47 of 539)
Problem [VM MB] : JMSTestApplet.class not found.
We have JMSTestApplet.java, but no javac
On another machine [P4], we do have javac
but not com.ibm.mq.jar (at <mq>\Java\lib),
so we install Java JDK 1.5 at VM-MB.
Puedo ejecutarlo sin browser :
javac JMSTestApplet.java
java JMSTestApplet
Desde Opera tengo este error :
Exception in thread "AWT-EventQueue-1" java.lang.NoClassDefFoundError: javax/jms/JMSException
Solució :
url :
The connector cannot find jms.jar Solution: make sure that jms.jar is in the connector classpath
How to connect to MQ using channel tab file in java
url
See also "Using Java" PDF.
MQ, Java i Francisco
MessageApplication.java
package com.ibm.iic;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class MessageApplication {
public static final String CONNECTION_FACTORY_JNDI_NAME = "jms/testConnFactory";
public static final String QUEUE_DESTINATION_JNDI_NAME = "jms/testQueue";
public static final String MESSAGE_TEXT = "Hola!";
protected ConnectionFactory cFactory = null;
protected Destination destination = null;
protected Destination dQueue = null;
public MessageApplication() {
super();
}
protected void findJNDIObjects ( String connectionFactory, String destination )
throws NamingException {
InitialContext jndiContext = new InitialContext();
cFactory = (ConnectionFactory) jndiContext.lookup ( connectionFactory==null ?
CONNECTION_FACTORY_JNDI_NAME: connectionFactory );
dQueue = (Destination) jndiContext.lookup ( destination==null ?
QUEUE_DESTINATION_JNDI_NAME : destination);
System.out.println(jndiContext);
System.out.println(dQueue);
}
public String sendMessage ( String connectionFactory, String destination, String message )
throws NamingException, JMSException {
findJNDIObjects(connectionFactory, destination);
Connection cnn = cFactory.createConnection();
cnn.start();
Session session = cnn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(/*dTopic*/dQueue);
TextMessage msg = session.createTextMessage();
msg.setText(message!=null ? message : MESSAGE_TEXT);
producer.send(msg);
System.out.println("Message sent: "+msg.toString());
cnn.close();
return msg.toString();
}
public String receiveMessage ( String connectionFactory, String destination, long millisWaiting )
throws NamingException, JMSException {
findJNDIObjects(connectionFactory, destination);
String result = null;
Connection cnn = cFactory.createConnection();
cnn.start();
Session session = cnn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(dQueue);
TextMessage msg = (TextMessage)consumer.receive(millisWaiting);
if (msg!=null)
result = msg.getText();
cnn.close();
return result;
}
} ; // public class
ConnectionFactory
Channel
The name of the channel used for connection to the WebSphere MQ queue manager, for client connection only (=> SVRCONN)
Transport type
Specifies whether the WebSphere MQ client connection or JNDI bindings are used for connection to the WebSphere MQ queue manager.
The external JMS provider controls the communication protocols between JMS clients and JMS servers.
Default BINDINGS
BINDINGS
JNDI bindings are used to connect to the queue manager.
BINDINGS is a shared memory protocol and can only be used when the queue manager is on the same node as the JMS client
and poses security risks that should be addressed through the use of EJB roles.
CLIENT
WebSphere MQ client connection is used to connect to the queue manager (=> SVRCONN)
url
Java MQ agent
It is very interesting to have these actions implemented in a Java node
to implement a "cluster agent" running in a MB flow :
- read current queue depth
- set CLWLPRTY property of a the queue ( see here )
read current queue depth
The Eclipse code is :
// QdepthCheck.java
import java.io.IOException ;
import com.ibm.mq.MQException ;
import com.ibm.mq.constants.MQConstants ;
import com.ibm.mq.pcf.* ; // PCFMessagAgent
// biblio
// PCFMessageAgent
// http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/index.jsp?topic=%2Fcom.ibm.mq.javadoc.doc%2FWMQJavaClasses%2Fcom%2Fibm%2Fmq%2Fpcf%2FPCFMessageAgent.html
public class QdepthCheck {
public static void main( String[] args ) {
try {
PCFMessageAgent agent ;
PCFMessage request ;
PCFMessage [] responses ;
System.out.println ( ">>> MQ Queue Depth Check using PCF, v 20140211a") ;
agent = new PCFMessageAgent ( "localhost", 2415, "SAG.SVRCONN" ) ;
System.out.print ( "+++ Connected" ) ;
// Build the request
request = new PCFMessage ( MQConstants.MQCMD_INQUIRE_Q ) ;
request.addParameter ( MQConstants.MQCA_Q_NAME, "QL.IN" ) ;
request.addParameter ( MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL ) ;
request.addParameter ( MQConstants.MQIACF_Q_ATTRS, new int [] { MQConstants.MQCA_Q_NAME, MQConstants.MQIA_CURRENT_Q_DEPTH } ) ;
// Use the agent to send the request
System.out.println ( ">>> Sending PCF request... ") ;
responses = agent.send ( request ) ;
System.out.println ( "+++ Received reply" ) ;
// Display the results
for ( int i = 0 ; i < responses.length ; i++ ) {
String name = responses [i].getStringParameterValue ( MQConstants.MQCA_Q_NAME ) ;
int depth = responses [i].getIntParameterValue ( MQConstants.MQIA_CURRENT_Q_DEPTH ) ;
System.out.println ( i + " - Queue [" + name + "], curdepth [" + depth +"]" ) ;
} ;
// Disconnect
System.out.print ( ">>> Disconnecting... " ) ;
agent.disconnect () ;
}
catch ( PCFException pcfe ) {
System.err.println ( "--- PCF error: " + pcfe ) ;
}
catch ( MQException mqe ) {
System.err.println ( mqe ) ;
}
catch ( IOException ioe ) {
System.err.println ( ioe ) ;
} ; // try
} ; // main
} ; // QdepthCheck
See \\T430\MQ\Java\PCF\Queue_Depth
Now we have to adapt it for a MB Java node ...
set queue priority
// QprioSet.java
// http://message-fixture.googlecode.com/svn-history/r10/trunk/src/main/java/com/googlecode/messagefixture/mq/util/PcfUtil.java
// package com.googlecode.messagefixture.mq.util;
import java.io.IOException;
import javax.jms.JMSException;
import com.ibm.mq.MQException;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.pcf.MQCFIN;
import com.ibm.mq.pcf.MQCFST;
import com.ibm.mq.pcf.PCFAgent;
import com.ibm.mq.pcf.PCFParameter;
import com.ibm.mq.pcf.PCFException; ;
public class PcfUtil {
public static void main( String[] args ) throws JMSException {
MQQueueManager qm = null ;
System.out.println( "+++ PCF UTIL, v 20140214.a - Michael i Sebastia" ) ;
try {
putDisableQueue( qm, "QLIN" ) ;
getDisableQueue( qm, "QLIN" ) ;
}
catch ( PCFException pcfe ) {
System.err.println ( "--- PCF error: " + pcfe ) ;
}
catch ( MQException mqe ) {
System.err.println ( mqe ) ;
}
catch ( IOException ioe ) {
System.err.println ( ioe ) ;
} ; // try
} ; // main()
public static void putDisableQueue( MQQueueManager qm, String queueName ) throws MQException, IOException, PCFException {
ableQueue( qm, queueName, MQConstants.MQIA_INHIBIT_PUT, MQConstants.MQQA_PUT_INHIBITED ) ; // 10 + 1
}
public static void putEnableQueue( MQQueueManager qm, String queueName ) throws MQException, IOException, PCFException {
ableQueue( qm, queueName, MQConstants.MQIA_INHIBIT_PUT, MQConstants.MQQA_PUT_ALLOWED ) ; // 10 + 0
}
public static void getDisableQueue( MQQueueManager qm, String queueName ) throws MQException, IOException, PCFException {
ableQueue( qm, queueName, MQConstants.MQIA_INHIBIT_GET, MQConstants.MQQA_GET_INHIBITED ) ; // 9 + 1
}
public static void getEnableQueue( MQQueueManager qm, String queueName ) throws MQException, IOException, PCFException {
ableQueue( qm, queueName, MQConstants.MQIA_INHIBIT_GET, MQConstants.MQQA_GET_ALLOWED ) ; // 9 + 0
}
private static void ableQueue( MQQueueManager qm, String queueName, int command, int value )
throws MQException, IOException, PCFException {
System.out.println ( ">>> ableQueue, cmd(" + command + "), value (" + value + ")" ) ;
PCFAgent agent = new PCFAgent( "localhost", 2415, "SAG.SVRCONN" ) ;
System.out.println ( "+++ Connected" ) ;
int queueType = MQConstants.MQQT_LOCAL ;
PCFParameter[] parameters = new PCFParameter[] {
new MQCFST( MQConstants.MQCA_Q_NAME, queueName ), // parameter
new MQCFIN( MQConstants.MQIA_Q_TYPE, queueType ), // fixed value = local queue
new MQCFIN( command, value ), } ; // command := value ;
try {
MQMessage[] pcfResponses = agent.send ( MQConstants.MQCMD_CHANGE_Q, parameters ) ;
System.out.println ( "+++ Received reply Able, lng(" + pcfResponses.length + ")" ) ;
PCFMessage response = new PCFMessage( pcfResponses[0] ) ;
int iCC = response.getCompCode() ;
int iRC = response.getReason() ;
int cnt = response.getParameterCount() ;
System.out.println ( "+++ able - paramCnt("+cnt+"), RC(" + iRC + "), CC(" + iCC + ")" ) ;
}
catch ( MQException mqe ) {
System.err.println ( mqe ) ;
}
catch ( IOException ioe ) {
System.err.println ( ioe ) ;
}
catch ( MQDataException mde ) {
System.err.println ( "--- MQ Data Exception error: " + mde ) ;
} ;
} ; // ableQueue()
} ; // class PcfUtil
See \\T430\MQ\Java\PCF\set_Queue
and \\T430\MQ\Java\PCF\Michael\pcfUtil_eclipse.java
code
Jeff came up with a better code
// code at \\T430\MQ\Java\PCF\jeff\jeff_setQ_eclipse.java
import java.io.IOException ;
import com.ibm.mq.MQException ;
import com.ibm.mq.constants.MQConstants ;
import com.ibm.mq.pcf.* ; // PCFMessageAgent
public class jeff_setQueue {
public static void main ( String[] args ) {
try {
System.out.println ( ">>> MQ Set Queue parameter using PCF by Jeff, v 20140215a") ;
PCFMessageAgent agent = new PCFMessageAgent ( "localhost", 2415, "SAG.SVRCONN" );
System.out.println ( "+++ Connected" ) ;
// Build the request
PCFMessage request = new PCFMessage ( MQConstants.MQCMD_CHANGE_Q ) ; // command := change the queue
request.addParameter ( MQConstants.MQCA_Q_NAME, "QLIN" ) ; // queue name
request.addParameter ( MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL ) ; // type of queue
request.addParameter ( MQConstants.MQIA_INHIBIT_GET, MQConstants.MQQA_GET_INHIBITED ) ; // set GET(DISABLED)
request.addParameter ( MQConstants.MQIA_CLWL_Q_PRIORITY, 3 ) ; // set priority **** **** ****
request.addParameter ( MQConstants.MQCA_Q_DESC, "New Descr" ) ; // set description text
PCFMessage[] responses = agent.send ( request ) ;
for ( PCFMessage pcfMessage : responses ) {
System.out.println ( pcfMessage ) ;
} ; // for
// Disconnect
System.out.println ( ">>> Disconnecting... " ) ;
agent.disconnect () ;
} // try
catch ( MQException mqe ) {
System.err.println ( mqe ) ;
}
catch ( IOException ioe ) {
System.err.println ( ioe ) ;
}
} ; // main()
} ; //
get queue priority
// code to read Cluster Priority for a queue
import java.io.IOException ;
import com.ibm.mq.MQException ;
import com.ibm.mq.constants.MQConstants ;
import com.ibm.mq.pcf.* ; // PCFMessagAgent
public class jeff_getQ {
public static void main( String[] args ) {
try {
System.out.println ( ">>> MQ Get Queue parameter using PCF by Jeff, v 20140215a") ;
PCFMessageAgent agent = new PCFMessageAgent( "localhost", 2415, "SAG.SVRCONN" );
System.out.println ( "+++ Connected" ) ;
// Build the request
PCFMessage request = new PCFMessage ( MQConstants.MQCMD_INQUIRE_Q ) ; // inquiry
request.addParameter ( MQConstants.MQCA_Q_NAME, "QLIN" ) ; // queue name
request.addParameter ( MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL ) ; // q type = local queue
request.addParameter ( MQConstants.MQIACF_CLUSTER_INFO, MQConstants.MQIA_CLWL_Q_PRIORITY ) ; // get actual priority
PCFMessage[] responses = agent.send ( request ) ;
System.out.println ( "+++ Received reply, lng ("+ responses.length + ")." ) ;
// for ( PCFMessage pcfMessage : responses ) {
// System.out.println ( pcfMessage ) ;
// } ; // for
for ( int i = 0; i < responses.length; i++ )
{
String name = responses [i].getStringParameterValue ( MQConstants.MQCA_Q_NAME ) ;
int prio = responses [i].getIntParameterValue ( MQConstants.MQIA_CLWL_Q_PRIORITY ) ;
System.out.println ( "Queue " + name + " cur prio (" + prio + ")" ) ;
} ;
// Disconnect
System.out.println ( ">>> Disconnecting... " ) ;
agent.disconnect () ;
} // try
catch ( MQException mqe ) {
System.err.println ( mqe ) ;
}
catch ( IOException ioe ) {
System.err.println ( ioe ) ;
}
} ; // main()
} ; //
mr fjb_saper has a nice (conceptual) improvement:
PCFMessage pcfmessage = null;
for ( int i = 0; i < responses.length; i++ )
{
pcfmessage = (PCFMessage) responses[i];
String name = pcfmessage.getStringParameterValue ( MQConstants.MQCA_Q_NAME ) ;
int prio = pcfmessage.getIntParameterValue ( MQConstants.MQIA_CLWL_Q_PRIORITY ) ;
System.out.println ( "Queue " + name + " cur prio (" + prio + ")" ) ;
} ;
change queue max depth
msgAgent = new PCFMessageAgent (localhost ,1414 channel);
PCFMessage request;
request = new PCFMessage ( MQCMD_CHANGE_Q ) ;
request.addParameter ( MQCA_Q_NAME, queueName ) ;
request.addParameter ( MQIA_Q_TYPE, MQQT_LOCAL ) ;
request.addParameter ( MQIA_MAX_Q_DEPTH, 100 ) ;
mqseries.net
PCF Agent vs PCF Message Agent
What is the difference ?
PCF Agent
The following example uses a PCFAgent to obtain the list of local queues on the queue manager.
//
PCFAgent agent = new PCFAgent ( "localhost", 1414, "CLIENT" ) ;
MQMessage[] responses;
PCFParameter[] parameters = {new MQCFST(CMQC.MQCA_Q_NAME, "*"),
new MQCFIN(CMQC.MQIA_Q_TYPE, MQC.MQQT_LOCAL)};
MQCFH cfh;
MQCFSL cfsl;
responses = agent.send(CMQCFC.MQCMD_INQUIRE_Q_NAMES, parameters);
cfh = new MQCFH(responses[0]);
if (cfh.reason == 0) {
cfsl = new MQCFSL(responses[0]);
for (int i = 0; i < cfsl.strings.length; i++) {
System.out.println("Queue: " + cfsl.strings[i]);
}
}
else {
throw new MQException(cfh.compCode, cfh.reason, agent);
}
url
PCF Message Agent
The following example uses a PCFMessageAgent to obtain the list of local queues on the queue manager.
//
import com.ibm.mq.pcf.*;
...
try
{
PCFMessageAgent agent = new PCFMessageAgent ( "localhost", 1414, "CLIENT" ) ;
PCFMessage request = new PCFMessage (CMQCFC.MQCMD_INQUIRE_Q_NAMES);
request.addParameter (CMQC.MQCA_Q_NAME, "*");
request.addParameter (CMQC.MQIA_Q_TYPE, MQC.MQQT_LOCAL);
PCFMessage [] responses = agent.send (request);
String [] names = (String []) responses [0].getParameterValue ( CMQCFC.MQCACF_Q_NAMES ) ;
for (int i = 0; i < names.length; i++)
{
System.out.println ( "Queue: " + names [i] );
}
}
catch (PCFException pcfe)
{
System.err.println ("PCF error: " + pcfe);
}
catch (MQDataException mqe)
{
System.err.println (mqe);
}
catch (IOException ioe)
{
System.err.println (ioe);
}
publib
User Properties
For application defined fields, which are easy to set using JMS:
jmsMsg.setStringProperty("StringPropertyName", "PropertyValue");
RFHutil
- on "Main" tab, check the "Yes" button inside "User Props"
- on "Usr Prop" tab, set values as "Event=37"
The result, in a TraceNode is :
(0x01000000:Name ):MQRFH2 = ( ['MQHRF2' : 0x2972b140]
(0x03000000:NameValue):Version = 2 (INTEGER)
(0x03000000:NameValue):Format = 'MQSTR ' (CHARACTER)
(0x03000000:NameValue):Encoding = 546 (INTEGER)
(0x03000000:NameValue):CodedCharSetId = 437 (INTEGER)
(0x03000000:NameValue):Flags = 0 (INTEGER)
(0x03000000:NameValue):NameValueCCSID = 1208 (INTEGER)
(0x01000000:Name ):usr = (
(0x01000000:Name):Event = (
(0x02000000:Value): = '37' (CHARACTER)
)
)
)
Initial values for dynamic structures
When a variable number of instances of a structure is required,
the instances are usually created in main storage
obtained dynamically using the calloc or malloc functions.
To initialize the fields in such structures,
the following technique is recommended:
-
Declare an instance of the structure using the appropriate MQxxx_DEFAULT macro variable to initialize the structure.
This instance becomes the "model" for other instances:
MQMD Model = {MQMD_DEFAULT} ; /* declare model instance */
The static or auto keywords can be coded on the declaration in order to give
the model instance static or dynamic lifetime, as required.
-
Use the calloc or malloc functions to obtain storage for a dynamic instance of the structure:
PMQMD Instance;
Instance = malloc( sizeof( MQMD ) ) ; /* get storage for dynamic instance */
- Use the memcpy function to copy the model instance to the dynamic instance:
memcpy( Instance, & Model, sizeof( MQMD ) ) ; /* initialize dynamic instance */
MQJMS1017: non-local MQ queue not valid for receiving or browsing
There are different type of queues -- all defined locally -- on a qmgr :
- queue local -- this one you can browse and receive from
- queue remote -- used as a pointer to a queue local on a different qmgr
- queue alias -- used as a pointer to queue on the same qmgr
- queue model -- used as a template for dynamic creation of a queue
- queue cluster -- when defined locally it can be accessed on a remote qmgr, within the cluster, as you would access a queue remote there.
- queue local usage xmitq -- a local queue serving to move messages from one qmgr to the other via a channel. It should never be directly posted to by the application
url
Verify Listener is running !
Another chance :
<bean id="jmsMQConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<!--property name="queueManager" value="QM.CBX2GSS2"/-->
<property name="hostName" value="192.168.219.80"/>
<property name="port" value="1442"/>
<property name="channel" value="CH.CBX2GSS.SRVC"/>
<property name="transportType" value="1"/>
</bean>
MQseries.net
mqjbnd05.dll
Si en ejecutar java JMS_Sender QD1 INDI
rebem un error
Exception in thread "main" java.lang.UnsatisfiedLinkError: no mqjbnd05 in java.library.path
... simplement vol dir que NO TENIM EL MQ INSTALAT !
FAQ for EasyJMS
Also can get this message after mqsilist MB command if MQ JRE is missing:
BIP8075E: A Java exception was caught from class 'com/ibm/broker/config/util/MQSIList.main'.
The text is 'java.lang.UnsatisfiedLinkError: mqjbnd05 (Not found in java.library.path)'.
A Java exception was caught via the JNI.
JMS Test
- copy code.
- origin : c:\Program Files\IBM\WebSphere MQ\Tools\Java\jms\applet
- destination : C:/TMP/MQ/Java/
- compile JMSTestApplet.java :
"c:\Program Files\IBM\Java142\bin\"JAVAC JMSTestApplet.java
- modify test.html :
- <APPLET CODE="JMSTestApplet.class" CODEBASE="."
- <PARAM name="queueManager" value="QM1">
- open test.html using Firefox
JMS tool - Performance_Harness_for_JMS
homepage
java -cp "perfharness.jar;%CLASSPATH%" JMSPerfHarness
JMS classes were not found on the classpath.
Include all of the (approximately 10) MQ jars in
C:\MQ\Java\lib\ on the classpath.
If you don't have 10 jars then you need to install the JMS client : re-run WMQ setup for this option.
java -cp "perfharness.jar;%CLASSPATH%" JMSPerfHarness
-tc jms.r11.Sender
-pc WebSphereMQ
-jb QMM1
-d QSEBAS
-jt mqb
-ms 100
-mg 10
Setting up a JMS queue in WebSphere MQ with LDAP
url
JMS trace
Tracing programs
WebSphere MQ classes for JMS
configuration file :
\\MQ\java\bin\jms.config
\\ The directory and file name to which trace output will be sent
com.ibm.msg.client.commonservices.trace.outputName
JMS providers
\\T400\C:\Documents and Settings\All Users\Application Data\IBM\MQSI\registry\MB7BROKER\CurrentVersion\ExternalResources\JMSProviders\
ActiveMQ
BEA_Weblogic
FioranoMQ
Generic_File
Generic_LDAP
JBoss
JOnAS
Joram
OpenJMS
Oracle_AQ
Oracle_OEMS
SeeBeyond
SonicMQ
SwiftMQ
Tibco_EMS
WebSphere_MQ
WebSphere_WAS_Client
Pendent
-
m'agradaria tenir un equivalent en Java al AMQSPUTC, al que no li calgués ni MQ server ni MQ client,
sino només Java ...
Solució: simplificar \\MQ\JMS\Stand_Alone_MQv6_JMSdemo\JMSDEMO\com\ibm\examples\JMSDemo.java from
here
Done :
\\MQ\JMS\Simplest_JMS\abc\SimplePTP.java !
- objectes :
-
MQConnectionFactory (JMS 1.1 only) - "Using Java", page 41 (59 of 539).
-
MQQueueConnectionFactory
-
MQTopicConnectionFactory
MQ Queue Connection Factory
settings (WAS v 5.1 book)
-
que osties vol dir
això :
Cuando se crea una fábrica de conexiones o un origen de datos,
se proporciona un nombre JNDI
para que un componente pueda buscar la fábrica de conexiones o el origen de datos.
Preferiblemente, se debe utilizar un nombre "indirecto"
con el prefijo java:comp/env en releases futuros.
El nombre "indirecto" permite
que los datos de referencia de recursos asociados a la aplicación
estén disponibles para la ejecución de gestión de conexiones,
con el fin de mejorar la gestión de los recursos basándose en los valores
res-auth, res-isolation-level, res-sharing-scope y res-resolution-control.
-
Writing Java tests for your WebSphere MQ environment to use in MQ Explorer
One of the innovations in WebSphere MQ V6 is Eclipse-based administration tools,
which lets you extend the WebSphere MQ Explorer toolset by using Eclipse plug-ins.
This article shows you how to use simple Java and XML to write a plug-in that performs a custom validation
on your WebSphere MQ environment.
-
how to write a
SAP
message (SUN Developer Network "Java Forums").