Cómo usar Java JMS con MQseries
ibm-mq (6)
Estoy tratando de desarrollar una aplicación independiente JMS para leer y escribir en una cola en MQSeries. Mi jefe me pidió que use Java JMS puro (no ibm.mq lib) para hacer eso.
Aquí está la información que necesita para hacer la conexión jms:
mq.hostname=10.10.10.10
mq.channel=API.CLIENTCHL
mq.queueManager=MQPETAPI
mq.port=1422
¿Sabes cómo hacer eso? ¿O tienes algún enlace que me enseñe a hacer eso?
Una aplicación JMS independiente (sincrónica) completa con TextMessage.
Es específico de IBM WebSphere MQ.
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueReceiver;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.ibm.mq.jms.JMSC;
import com.ibm.mq.jms.MQQueueConnectionFactory;
public class JMSApplicationStandAlone {
public static void main(String[] args) {
try {
/*MQ Configuration*/
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName("localhost");
mqQueueConnectionFactory.setChannel("MQ.CHANNEL");//communications link
mqQueueConnectionFactory.setPort(1416);
mqQueueConnectionFactory.setQueueManager("QUEUE.MGR");//service provider
mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
/*Create Connection */
QueueConnection queueConnection = mqQueueConnectionFactory.createQueueConnection();
queueConnection.start();
/*Create session */
QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
/*Create response queue */
Queue queue = queueSession.createQueue("QUEUE.RESPONSE");
/*Create text message */
TextMessage textMessage = queueSession.createTextMessage("put some message here");
textMessage.setJMSReplyTo(queue);
textMessage.setJMSType("mcd://xmlns");//message type
textMessage.setJMSExpiration(2*1000);//message expiration
textMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT); //message delivery mode either persistent or non-persistemnt
/*Create sender queue */
QueueSender queueSender = queueSession.createSender(queueSession.createQueue("QUEUE.REQEST"));
queueSender.setTimeToLive(2*1000);
queueSender.send(textMessage);
/*After sending a message we get message id */
System.out.println("after sending a message we get message id "+ textMessage.getJMSMessageID());
String jmsCorrelationID = " JMSCorrelationID = ''" + textMessage.getJMSMessageID() + "''";
/*Within the session we have to create queue reciver */
QueueReceiver queueReceiver = queueSession.createReceiver(queue,jmsCorrelationID);
/*Receive the message from*/
Message message = queueReceiver.receive(60*1000);
String responseMsg = ((TextMessage) message).getText();
queueSender.close();
queueReceiver.close();
queueSession.close();
queueConnection.close();
} catch (JMSException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Nota: Reemplace los valores de configuración
El problema aquí es el requisito de que "Mi jefe me pidió que use Java JMS puro (no ibm.mq lib) para hacer eso". JMS es una especificación y cada implementación debe cumplir con la API y la semántica, pero es libre de hacer lo que quiera en un nivel bajo. Siempre es necesario utilizar las clases de implementación proporcionadas por el proveedor de transporte. Por lo tanto, si usa WebSphere MQ como transporte, deberá usar las clases JMS de IBM MQ para escribir una aplicación JMS.
Dicho esto, si se atiene a las llamadas JMS API puras, podrá conectar las clases de cualquier proveedor de transporte. Esto es lo que generalmente se pretende cuando se le dan requisitos como el mencionado en la publicación original.
Hay un artículo que describe exactamente lo que estás buscando hacer. Ejecutar una aplicación Java independiente en WebSphere MQ V6.0. Utiliza solo la API JMS y utiliza JNDI en un sistema de archivos local (un archivo .bindings). Al intercambiar las clases de IBM JMS por otro proveedor y utilizar sus herramientas JNDI, podrá conectar cualquier transporte JMS sin cambiar su código con este enfoque.
Si quiere hacer lo mismo sin JNDI, mire los programas de muestra provistos con la instalación del cliente de MQ donde obtuvo sus clases de Java. En un sistema UNIX / Linux estos se encuentran en /opt/mqm/samp
y en Windows están en install_dir/tools/jms/samples
. La muestra SimpleRequestor.java
tiene el siguiente código para inicializar su fábrica de conexiones sin JNDI:
try {
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, "localhost");
cf.setIntProperty(WMQConstants.WMQ_PORT, 1414);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, "SYSTEM.DEF.SVRCONN");
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "QM1");
Debido a que este enfoque no utiliza JNDI, debe escribir un código que no sea transportable entre los proveedores de transporte. Es específico de IBM WebSphere MQ.
Si agarró los tarros de MQ de algún lugar y no tiene la instalación completa (y por lo tanto no tiene los ejemplos), puede descargarlo como SupportPac MQC7 . La descarga es gratis. En general, debe usar el último cliente, incluso con un administrador de cola de nivel posterior. Obviamente, usted no obtiene la funcionalidad V7 de un V6 QMgr, pero la implementación de JMS en el cliente V7 ha mejorado mucho, incluso para la funcionalidad V6. Si por alguna razón realmente debe usar el cliente V6, puede descargarlo como SupportPacMQC6 . Cualquiera que sea la versión del cliente que use, asegúrese de usar el Infocenter correspondiente.
Finalmente, la página de inicio con un índice para todos los SupportPacs está here .
Esto es bastante común. Here hay algunos ejemplos.
No puedo enseñarte JMS en una sola publicación, pero puedo señalarte algunos de los recursos que usé para aprenderlo yo mismo:
- El libro de O''Reilly Java Message Service
- IBM Developerworks JMS Tutorial (más MQSeries / Websphere MQ específico)
- El marco Spring puede ayudarlo a usar JMS de manera más efectiva, especialmente si está desarrollando una aplicación independiente fuera de un servidor de aplicaciones J2EE: documentación de Spring Java Message Service
Normalmente, con JMS definiría QueueConnectionFactory
en su contenedor a través de cualquier mecanismo de configuración disponible y luego lo agregará al registro JNDI del contenedor. Cada contenedor tendría sus propios métodos para hacerlo (es decir, Tomcat versus WebSphere).
Si desea renunciar a JNDI, puede crear una instancia de com.ibm.mq.jms.MQQueueConnectionFactory
directamente y establecer el nombre de host, el puerto, el queueManager y las propiedades del canal. A continuación, puede usar ese objeto como lo haría con una instancia de javax.jms.QueueConnectionFactory
ya que lo implementa.
Si no te importa escribir código específico de WMQ, entonces puedes hacer
MQConnectionFactory cf = new MQConnectionFactory();
cf.setHostName(HOSTNAME);
cf.setPort(PORT);
cf.setChannel(CHANNEL);
cf.setQueueManager(QMNAME);
cf.setTransportType(WMQConstants.WMQ_CM_CLIENT);
entonces los recursos JMS usuales
Connection c = cf.createConnection();
Session s = c.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue q = s.createQueue("myQueue"); // replace with real queue name
MessageProducer p = s.createProducer(q);
y finalmente crea y envía un mensaje
Message m = s.createTextMessage("Hello, World!);
p.send(m);
(He escrito eso en la parte superior de mi cabeza, así que no puedo descartar un error tipográfico, pero es fundamentalmente correcto). Si se supone que debes usar ''JMS puro'', es decir, sin objetos específicos del proveedor, debes vincular un objeto MQConnectionFactory en JNDI (mira la herramienta JMSAdmin, está en los documentos) y luego búscalo. de su aplicación, es decir,
InitialContext ic = new InitialContext(); // or as appropraite
ConnectionFactory cf = (ConnectionFactory)ic.lookup("myMQfactory"); // replace with JNDI name