2011-08-04 17 views
29

Estoy tratando de desarrollar una aplicación independiente JMS para leer y escribir en una cola en MQSeries. Mi jefe me pidió que usara Java JMS puro (no ibm.mq lib) para hacer eso.Cómo usar Java JMS con MQseries

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 

¿Usted sabe cómo hacer eso ¿O usted tiene cualquier vínculo que me enseñe a hacer eso.

+1

Haga su código se ejecute dentro de WebSphere Application Server y luego se conecta a WebSphere MQ para la mensajería, o es su aplicación está sola y quiere conectarse a WebSphere MQ para ¿mensajería? –

Respuesta

46

el tema aquí es el requisito de que "Mi jefe me pidió usar JMS Java 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á buscando hacer llamada Running a standalone Java application on WebSphere MQ V6.0 Sólo utiliza la API de JMS y JNDI utiliza en un sistema de archivos local (un archivo de .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 desea 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 están 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"); 

Dado que este enfoque no utiliza JNDI, se le requiere para escribir código que no es transportable a través de los proveedores de transporte. Es específico de IBM WebSphere MQ.

Si agarrado los frascos MQ desde algún lugar y no tiene la instalación completa (y por lo tanto no tienen las muestras) se puede descargar 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.

V6 Infocenter
V7 Infocenter

Por último, la página de destino con un índice de todos los SupportPacs es here.

+1

"Por lo tanto, si usa WebSphere MQ como transporte, deberá usar las clases JMS de IBM MQ para escribir una aplicación JMS". Creo que eso solo es cierto si trabajas directamente con MQ. Si se abstrae a través de un contenedor como WebSphere Application Server, puede escribir código "JMS puro" ya que el contenedor de la aplicación se ocupa de que trabaje con MQ como si trabajara con la implementación de SIBus. Todo lo que tiene que hacer es asegurarse de que sus Colas MQ estén definidas como "Colas" JMS y que tenga una QueueConnectionFactory (interfaz con como si fuera una ConnectionFactory). –

+2

Este es un baile semántico interesante.Las clases JMS del proveedor de transporte * son * en CLASSPATH de una forma u otra. En su ejemplo, el servidor JEE proporciona un contenedor dentro del cual se accede a las bibliotecas IBM MQ JMS. Pero de cualquier manera, la aplicación todavía está usando esas clases específicas * y puede acceder a los métodos específicos de su proveedor *. No es como si el servidor JEE de alguna manera oculta la implementación del proveedor de la aplicación, por lo que me parece una distinción sin sentido. Además, OP especificó una aplicación JMS independiente, así que presumiblemente no hay un contenedor JEE en su escenario de todos modos. –

+0

Gracias a todos ustedes por dedicar tiempo a mi pregunta. Especialmente a T.Rob – David

0

Esto es bastante común. Here son algunos ejemplos.

+0

Thnaks. ¿Cómo puedo poner (nombre de host, canal, puerto, queueManager) en el obj de conexión? – David

+0

@David: no puedes. JMS requiere que use JNDI para eso. –

+1

@ Cosmic.osmo: consulte las otras respuestas para ver ejemplos de cómo establecer las propiedades del objeto CF sin JNDI. JMS deja que el proveedor de transporte especifique exactamente qué propiedades establecer y qué valores usar. La especificación JMS lo prohíbe ni impone de ninguna manera que esto deba hacerse a través de JNDI. –

2

Por lo general, con JMS definiría el QueueConnectionFactory en su contenedor a través de cualquier mecanismo de configuración disponible y luego lo agrega 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. Luego puede usar ese objeto como lo haría con una instancia de javax.jms.QueueConnectionFactory ya que lo implementa.

2

que no se puede enseñar a JMS en un solo puesto, pero se puede apuntar a algunos de los recursos que he usado para aprender yo mismo:

  1. El O'Reilly Java Message Service libro
  2. IBM Developerworks JMS Tutorial (más MQSeries/Websphere MQ específica)
  3. El framework Spring puede ayudarle a utilizar JMS de manera más eficaz, especialmente si está desarrollando una aplicación independiente fuera de un servidor de aplicación J2EE: Spring Java Message Service documentation
8

Si no te importa la escritura de código-WMQ específico, entonces se puede hacer

MQConnectionFactory cf = new MQConnectionFactory(); 
cf.setHostName(HOSTNAME); 
cf.setPort(PORT); 
cf.setChannel(CHANNEL); 
cf.setQueueManager(QMNAME); 
cf.setTransportType(WMQConstants.WMQ_CM_CLIENT); 

recursos JMS entonces habituales

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, crear y enviar 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. desde la aplicación, es decir

InitialContext ic = new InitialContext(); // or as appropraite 
ConnectionFactory cf = (ConnectionFactory)ic.lookup("myMQfactory"); // replace with JNDI name 
8

Completo (síncrono) aplicación JMS independiente con TextMessage.
Es IBM WebSphere MQ específico.

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: Cambie la configuración valora

+0

Gracias. Esto me ayudó cuando estaba probando un código que se conectaba a IBM MQ. –