Introducción a JMS (Java Message Service)

JMS es la solución de Sun para los sistemas de mensajes, empecemos por saber que es un sistema de mensajes empresarial:

En las comunicaciones cliente servidor, los datos que se intercambian entre las dos partes necesitan de una comunicación sincrona, es decir, que las dos partes esten presentes en el momento de la comunicación. Los sistemas de mensajes aportan una serie de mejoras a la comunicación entre aplicaciones que no tienen por que residir en la misma máquina.

JMS se situa como middleware en medio de la comunicación de dos aplicaciones. En entornos cliente servidor, cuando la aplicación A quiere comunicarse con la Aplicación B, necesita saber donde esta B (su IP por ejemplo) y que B esté escuchando en ese momento. Cuando se usa JMS (o cualquier otro sistema de mensajes), la aplicación A envía un mensaje, el sistema de mensajes lo recibe y se lo envía a B cuando se conecte al servicio. De esta manera se consigue una comunicación asíncrona entre A y B, es decir no hace falta que B este presente en el momento del envío del mensaje, y no por ello va a dejar de recibirlo.

La anterior es una de las ventajas de JMS, pero no la única. La comunicación anterior tiene dos extremos, el productor (A) y el consumidor (B). JMS soporta otro tipo de comunicaciones que Sun denomina Publisher/Subscriber, traducido seria Publicador (Publicante)/Suscriptor. En este tipo de comunicación, la aplicación A publica su mensaje en el servicio JMS y lo reciben todas las aplicaciones que esten suscritas al servicio JMS al que se envió el mensaje, esta forma de comunicación es exactamente igual que la que se produce el los chats del IRC.

Otra de las ventajas de usar JMS (o cualquier otro sistema de mensajes) es que las aplicaciones se pueden cambiar simplemente asegurándose que la nueva aplicación entiende los mensajes que se intercambian.

NOTA: Los ejemplos de este artículo han sido probados con JDK 1.3.1 y J2EE 1.3.01, no se asegura que funcionen en otras versiones, sobre todo inferiores.

Arquitectura de JMS

Una aplicación JMS consta de los siguientes elementos:

Clientes JMSAplicaciones que envian o reciben mensajes a través de JMS
MensajesLos mensajes que se intercambian
Objetos administradosLos 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 corazón del sistema de mensajes. Estan formados por tres elementos:

Header: Es la cabecera del mensaje, contiene una serie de campos que le sirven a los clientes y proveedores a identificar a los mensajes. Aquí tines la lista de campos completa :

CampoTipo de DatoDescripcion
JMSMessageIDStringUn numero que identifica univocamente al mensaje. Solo se puede consultar una vez que esta enviado el mensaje.
JMSDestinationDestinationEl destino a donde se envia el mensaje.
JMSDeliveryModeintPuede ser de tipo PERSISTENT, entonces se envia una unica vez, o de tipo NON_PERSISTEN, de manera que se envia como mucho una vez, lo cual incluye tambien que no sea enviado nunca. PERSISTENT y NON_PERSISTENT estan definidas como constantes.
JMSTimestamplongPues eso, la hora a la que se envio el mensaje.
JMSExpirationlongLa hora hasta la cual el mensaje es valido, si es 0 quiere decir que no caduca nunca.
JMSPriorityintPrioridad del mensaje de 0 a 9, siendo 0 la mas baja.
JMSCorrelationIDStringEste campo se usa para relaccionar una respuesta a un mensaje, se copia aqui el id de mensaje del mensaje al que se esta respondiendo.
JMSReplyToDestinationEspecifica el lugar a donde se deben enviar las respuestas al mensaje actual.
JMSTypeStringEste campo lo puede usar el programa de mensajeria para almacenar el tipo del mensaje.
JMSRedeliveredbooleanIndica que el mensaje ha sido enviado con anterioridad pero el destino no lo ha procesado, por lo que se reenvia.

Properties: Son propiedades personalizadas para un mensaje en particular. Aquí tienes la lista completa:

PropiedadTipo de DatoDescripcion
JMSXUserIDStringEl usuario que envia el mensaje.
JMSXApplIDStringLa aplicacion que envia el mensaje.
JMSXDeliveryCountintEl numero de veces que se ha intentado enviar el mensaje
JMSXGroupIDStringIdentificador del grupo al que pertenece el mensaje.
JMSXGroupSeqintNumero de secuencia en el grupo de mensajes.
JMSXRcvTimestamplongLa hora a la que JMS le entrego el mensaje al/los destinatario/s.
JMSXStateintPara uso del proveedor de mensajeria.
JMSX_<nombre_del_proveedor>-Reservado para propiedades particulares del proveedor.

Body: Es el mensaje en si, hay distintos tipos:

  • StreamMessage: Contiene un stream de datos que se escriben y leen de manera secuencial.
  • MapMessage: Contiene pares nombre-valor.
  • TextMessage: Contiene un String.
  • ObjectMessage: Contiene un objeto que implemente la interfaz Serializable.
  • BytesMessage: Contiene un stream de bytes.

Clientes JMS

Son clientes de JMS tanto el que suministra mensajes como el que los recibe. Todos tienen una serie de pasos en común antes de lograr enviar o recibir un mensaje:

  • Conseguir un objeto ConnectionFactory a través de JNDI.
  • Conseguir un destino, mediante el objeto Destination a través de JNDI.
  • Usar ConnectionFactory para conseguir un objeto Connection
  • Usar Destination para crear un objeto Session.

Aplicaciones punto a punto

En las conexiones punto a punto, es decir, con solo dos extremos en la comunicación, el que envía y el que recibe, el destino en el que se reciben los mensajes enviados y de donde se recogen los mensajes recibidos recibe el nombre de Cola de mensajes (en inglés Queue) y actúa como una cola FIFO (el primer mensaje que llega es el primer mensaje que se recoge).

Vamos a seguir los pasos que necesita un cliente JMS para conseguir una conexión a una cola de mensajes.

  • Primero debemos crear un contexto inicial para JNDI:
  • 	InitialContext contextoInicial = new InitialContext();
    
  • Recuperamos de este contexto el objeto QueueConnectionFactory
  • 	QueueConnectionFactory factory =
    		(QueueConnectionFactory)contextoInicial.lookup("QueueConnectionFactory");
    
  • Recuperamos de la JNDI la cola de mensajes
  • 	Queue cola = (Queue)contextoInicial.lookup("Cola");
    
  • Mediante el metodo createQueueConnection() de factory conseguimos un objeto QueueConnection.
  • 	QueueConnection conexion = factory.createQueueConnection();
    
  • El objeto anterior nos sirve ahora para crear una sesión, los parámetros los comentaremos mas tarde:
  • 	QueueSession sesion =
    		conexion.createQueueSession(false,sesion.AUTO_ACKNOWLEDGE);
    

A partir de ahora ya podriamos crear mensajes y enviarlos. Vamos a ver un ejemplo sencillo de una comunicación punto a punto.

Ejemplo de una comunicación punto a punto

Para poder probar los ejemplos, necesitamos tener instalada la J2EE 1.3 o superior (es donde viene la api JMS, en el paquete javax.jms) y el classpath debe incluir a j2ee.jar. Esto será requisito previo para la compilación y ejecución de todos los ejemplos.

Antes de compilar y ejecutar los ejemplos, debemos crear los objetos administrados que usaremos en los ejemplos:

  • Ejecutamos el servidor J2EE: j2ee -verbose
  • .
  • Entre el montón de mensajes que imprime, divisamos QueueConnectionFactory, es el ConnectionFactory por defecto.
  • Crearemos un destino para nuestros mensajes: j2eeadmin -addJmsDestination Cola queue
  • Esto crea un Destination llamado Cola del tipo queue, comprobamos que esta creado: j2eeadmin -listJmsDestination

Esta es la clase que envía mensajes a la cola EnviaCola.java:

import javax.jms.*;
import javax.naming.*;

public class EnviaCola{
	public static void main (String args[]){
		InitialContext contextoInicial = null;
		QueueSession sesion = null;
		try {
			// Conseguimos de la JNDI los objetos administrados
			contextoInicial = new InitialContext();
			QueueConnectionFactory factory =
			(QueueConnectionFactory)contextoInicial.lookup("QueueConnectionFactory");
			Queue cola = (Queue)contextoInicial.lookup("Cola");
			// Creamos la conexion y la sesion
			QueueConnection conexion = factory.createQueueConnection();
			sesion = conexion.createQueueSession(false,sesion.AUTO_ACKNOWLEDGE);
			// Creamos una sesion de envio
			QueueSender enviaACola = sesion.createSender(cola);
			// Creamos un mensaje
			TextMessage mensaje = sesion.createTextMessage();
			mensaje.setText("Esto es un mensaje");
			// Lo enviamos
			enviaACola.send(mensaje);
			System.out.println("Mensaje enviado: " + mensaje.getText());
			// Cerramos la conexion
			conexion.close();
		} catch (NamingException e){
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
}

Esta es la clase que recibe los mensajes de la cola RecibeCola.java:

import javax.jms.*;
import javax.naming.*;

public class RecibeCola{
	public static void main (String args[]){
		InitialContext contextoInicial = null;
		QueueSession sesion = null;
		try {
			// Conseguimos de la JNDI los objetos administrados
			contextoInicial = new InitialContext();
			QueueConnectionFactory factory =
			(QueueConnectionFactory)contextoInicial.lookup("QueueConnectionFactory");
			Queue cola = (Queue)contextoInicial.lookup("Cola");
			// Creamos la conexion y la sesion
			QueueConnection conexion = factory.createQueueConnection();
			sesion = conexion.createQueueSession(false,sesion.AUTO_ACKNOWLEDGE);
			// Creamos una sesion de recepcion
			QueueReceiver recibeDeCola = sesion.createReceiver(cola);
			// Iniciamos la recepcion de mensajes
			conexion.start();
			while (true) {
				// Cogemos un mensaje de la cola, el 1 indica que esperara 1 milisegundo
				Message mensaje= recibeDeCola.receive(1);
				if (mensaje != null){
					if (mensaje instanceof TextMessage){
						// Lo mostramos
						TextMessage m = (TextMessage)mensaje;
						System.out.println("Recibido mensaje:  " + m.getText());
					}
				} else {
					// No hay mas mensajes
					break;
				}
			}
			// Cerramos la conexion
			conexion.close();
		} catch (NamingException e){
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
}

Ahora ya podemos compilar los ejemplos: EnviaCola.java, RecibeCola.java:

	javac EnviaCola.java
	javac RecibeCola.java

Y ejecutarlos. Primero enviamos un mensaje:

	java EnviaCola

Y luego recogemos los mensajes de la cola:

	java RecibeCola

Aplicaciones orientadas a suscripción

Este el otro tipo de aplicaciones que maneja el API JMS. Aqui ya no hay una aplicación que envía y otra que recibe, sino que son varias las aplicaciones que reciben los mensajes, en concreto aquellas que este suscritas a la cola a la que se envian los mensajes.

La primera parte de toda aplicación que use JMS es igual, hay que recoger los objetos administrados y crear los objetos de JMS:

  • Primero debemos crear un contexto inicial para JNDI:
  • 	InitialContext contextoInicial = new InitialContext();
    
  • Recuperamos de este contexto el objeto TopicConnectionFactory
  • 	TopicConnectionFactory factory =
    		(TopicConnectionFactory)contextoInicial.lookup("TopicConnectionFactory");
    
  • Recuperamos de la JNDI la cola de mensajes a la que nos suscribiremos:
  • 	Topic asunto = (Topic)contextoInicial.lookup("asunto");
    
  • Mediante el metodo createQueueConnection() de factory conseguimos un objeto QueueConnection.
  • 	TopicConnection conexion = factory.createTopicConnection();
    
  • El objeto anterior nos sirve ahora para crear una sesión, los parámetros los comentaremos mas tarde:
  • 	TopicSession sesion =
    		conexion.createTopicSession(false,sesion.AUTO_ACKNOWLEDGE);
    

Podemos observar que practicamente solo hay que sustituir Queue por Topic.

Ejemplo de una comunicacion orientada a la suscripción

Primero crearemos los objetos distribuidos que usaremos en los ejemplos. Suponiendo que el servidor J2EE ya esta iniciado:

	j2eeadmin -addJmsDestination asunto topic

Y comprobamos que esta creada:

	j2eeadmin -listJmsDestination

Esta es la clase que envia mensajes al asunto EnviaAsunto.java, vemos que es practicamente igual a EnviaCola.java:

import javax.jms.*;
import javax.naming.*;

public class EnviaAsunto{
	public static void main (String args[]){
		InitialContext contextoInicial = null;
		TopicSession sesion = null;
		try {
			// Conseguimos de la JNDI los objetos administrados
			contextoInicial = new InitialContext();
			TopicConnectionFactory factory =
			(TopicConnectionFactory)contextoInicial.lookup("TopicConnectionFactory");
			Topic asunto = (Topic)contextoInicial.lookup("asunto");
			// Creamos la conexion y la sesion
			TopicConnection conexion = factory.createTopicConnection();
			sesion = conexion.createTopicSession(false,sesion.AUTO_ACKNOWLEDGE);
			// Creamos una sesion de envio
			TopicPublisher enviaAAsunto = sesion.createPublisher(asunto);
			// Creamos un mensaje
			TextMessage mensaje = sesion.createTextMessage();
			mensaje.setText("Esto es un mensaje");
			// Lo enviamos
			enviaAAsunto.publish(mensaje);
			System.out.println("Mensaje enviado: " + mensaje.getText());
			// Cerramos la conexion
			conexion.close();
		} catch (NamingException e){
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
}

Esta es la clase que recibe los mensajes del asunto RecibeAsunto.java:

import javax.jms.*;
import javax.naming.*;

public class RecibeAsunto implements MessageListener{
	public static void main (String args[]){
		new RecibeAsunto().suscribe();
	}
	public void suscribe(){
		InitialContext contextoInicial = null;
		TopicSession sesion = null;
		try {
			// Conseguimos de la JNDI los objetos administrados
			contextoInicial = new InitialContext();
			TopicConnectionFactory factory =
			(TopicConnectionFactory)contextoInicial.lookup("TopicConnectionFactory");
			Topic asunto = (Topic)contextoInicial.lookup("asunto");
			// Creamos la conexion y la sesion
			TopicConnection conexion = factory.createTopicConnection();
			sesion = conexion.createTopicSession(false,sesion.AUTO_ACKNOWLEDGE);
			// Creamos una sesion de suscripcion
			TopicSubscriber suscrito = sesion.createSubscriber(asunto);
			// Añadimos nuestro listener para recibir mensajes
			suscrito.setMessageListener(this);
			// Iniciamos la recepcion
			conexion.start();
		} catch (NamingException e){
			e.printStackTrace();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	public void onMessage(Message mensaje){
		// Se recibe un mensaje
		try{
			// Si es un mensaje de texto, lo mostramos
			if (mensaje instanceof TextMessage){
				TextMessage m = (TextMessage)mensaje;
				System.out.println("Mensaje recibido: " + m.getText());
			}
		} catch (JMSException e){
			e.printStackTrace();
		}
	}
}

Esta clase es un poco diferente al ejemplo anterior. La diferencia mas importante es que esta clase implementa la interfaz MessageListener, que tiene un método (public void onMessage(Message mensaje) que hay que sobreescribir con el codigo que queremos que se ejecute al recibir un mensaje. El resto del codigo es practicamente igual, a excepción de que antes de iniciar la descarga de mensajes con el método start(), debemos indicarle la clase que implementa MessageListener mediante el método setMessageListener() del objeto TopicSubscriber.

Características mas avanzadas

Vamos a entrar ahora en características un poco mas avanzadas, la primera es el reconocimiento de mensajes o en inglés Message Acknowledgment. Mediante esta característica un mensaje enviado no se elimina de donde lo tenga guardado la JMS hasta que no sea reconocido por el consumidor de los mensajes. Este reconocimiento se realiza llamando al método acknowledge() del mensaje. Para que sea el cliente el que reconozca los mensajes y no la JMS, hay que crear una sesión con la constante CLIENT_AKNOWLEDGE, como parámetro.

Para comprobar esto, podemos enviar mensajes a nuestra cola con el ejemplo anterior, EnviaCola. Y los recogeremos en este caso con RecibeColaReconocimiento.java.

Compilamos con javac RecibeColaReconocimiento.java, enviamos un mensaje a la cola java EnviaCola y recibimos varias veces el mensaje con java RecibeColaReconocimiento. Como podemos ver, el mensaje no se elimina de la cola por que no lo estamos reconociendo, para hacer esto ejecutamos java RecibeColaReconocimiento reconoce, de manera que reconocemos el mensaje recibido y las siguientes ejecuciones no recibirán ningun mensaje (ya no existe en la cola) hasta que no se envíe otro.

Otra característica avanzada es la capacidad de establecer niveles de prioridad. Para establecer los niveles de prioridad de los mensajes hay dos maneras, invocando el método setPriority de la interfaz MessageProducer (que la implementan los objetos QueueSender y TopicPublisher) o invocar la forma larga de los métodos send() y publish() según la conexión sea punto a punto o orientada a la suscripción. Para ver esto, tenemos una clase (EnviaColaPrioridad.java) que envia 10 mensajes a una cola con prioridad aumentando de menor(0) a mayor(9), una vez compilada la clase y enviados los mensajes, podemos ejecutar RecibeCola (invocando java RecibeCola) y ver que se reciben en orden inverso a como se enviaron en correspondencia con los niveles de prioridad asignados.

Vamos con otra característica mas, que hemos visto implícitamente en el ejemplo anterior, la duración de los mensajes. A los mensajes se les puede establecer una duración a partir de la cual los mensajes dejan de ser válidos. Para esto podemos usar el método setTimeToLive() de la interfaz MessageProducer o podemos especificarlo en el método send() o publish() dependiendo del tipo de servicio. Podemos modificar el ejemplo anterior sustituyendo:

	enviaACola.send(mensaje,DeliveryMode.NON_PERSISTENT,i,0);

por

	enviaACola.send(mensaje,DeliveryMode.NON_PERSISTENT,i,1000);

De esta manera conseguimos que los mensajes caduquen (y por lo tanto no se distribuyan) si no se solicitan antes de un segundo. El valor del TimeToLive (tiempo de caducidad) se expresa en milisegundos, un valor igual a 0 indica que el mensaje no caduca nunca.

En los dos últimos ejemplos anteriores, en el método send() hemos estado usando una constante de la que no hemos definido su uso, DeliveryMode.NON_PERSISTENT. Pues bien esta constante establece la persistencia del mensaje, hay dos valores posibles, DeliveryMode.NON_PERSISTENT y DeliveryMode.PERSISTENT, que indican si el proveedor de los servicios JMS asegura que el mensaje no se perderá en caso de que falle el servicio. El valor PERSISTENT asegura que el mensaje sera almacenado de una manera estable para poder recuperarse a fallos. Y los NON_PERSISTENT no garantizan esto último. Puede modificar el codigo de los ejemplos anteriores y tomar las medidas oportunas (apagar el servidor de JMS, etc..) para comprobarlo.

Mas características avanzadas

En esta sección vamos a ver dos características mas de JMS, las suscripciones persistentes y las transacciones.

Empezamos por las suscripciones persistentes. Mediante este método conseguimos la versatilidad de las colas en los entornos orientados a la suscripción, conseguimos que alguien suscrito a un asunto en particular, reciba los mensajes enviados mientras no estaba conectado. Para demostar este comportamiento, tenemos cinco clases (cuyo origen no quiero recordar, :)), en todo caso no las he hecho yo), DurableSubscriber.java, es el suscriptor, MultiplePublisher.java, publica los mensajes, TextListener.java, implementa la interfaz MessageListener y sera la que trate los mensajesMonitor.java, monitoriza que el listener no este ocupadoDurableSubscriberExample.java, ejecuta al resto de clases, tiene el método main. La clase principal es DurableSubscriberExample, que invoca al resto de clases. Para poder probar esto, debemos definir un destino para la suscripción persistente: j2eeadmin -addJmsFactory TopicDurable topic -props clientID=MyID.Al compilar las cinco clases y ejecutar DurableSubscriberExample, primero activa el suscriptor, envía 3 mensajes y se reciben, luego desactiva al suscriptor y envía otros 3 mensajes, activa el suscriptor y automáticamente se reciben los mensajes recibidos mientras el suscriptor estaba desconectado.

Las Transacciones son un mecanismo por el cual una serie de operaciones se consideran como un todo, lo que quiere decir que o se ejecutan todas correctamente, o no se ejecuta ninguna. Un ejemplo típico de uso de transacciones son las bases de datos de los bancos, cuando se hace un ingreso hay que actualizar varias tablas correctamente o si no la informacion contenida en ellas no sera consistente, imaginemos un traspaso de una cuenta a otra, hay dos operaciones básicas, sacar de una cuenta e ingresar el dinero en otra, si se saca de una cuenta y no se llega a meter en otra tenemos un problema ( y un cliente cabreado ), por lo que el traspaso se considera como una transacción, o se completan todos los pasos con exito o se vuelve atrás, al punto donde se inició la transacción. Las transacciones tienen dos operaciones basicas, commit, que crea una nueva transacción (y termina correctamente la anterior), y rollback, que anula una transacción y deshace las operaciones realizadas durante la misma. Pues bien, en JMS tambien existen transacciones, recordemos como creabamos una sesión:

	sesion = conexion.createTopicSession(false,sesion.AUTO_ACKNOWLEDGE);

el primer parámetro le indica a JMS que la sesion no soportara transacciones (en realidad cada una de las operaciones es una transicion aceptada). Para que nuestras sesiones con la JMS sean transaccionales llamaremos a este metodo con el primer parámetro a true. Todas las sesiones de JMS, el que envia a una cola, el que recibe de una cola, y sus homólogos en suscripciones, se pueden declarar para que soporten transacciones. Iniciaremos una transacción (y validaremos la anterior) invocando al método commit() de la interfaz Session y usaremos el método rollback() de la misma interfaz para deshacer una transaccion.

Las clase EnviaColaTrans.java demuestra el uso de transacciones en una cola. Esta clase enviará cuatro mensajes, de los cuales solo deben llegar 2. Podemos recibir los mensajes enviados, con la clase RecibeCola de uno de los ejemplos anteriores.

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 este 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 aplicacion J2EE sea capaz de recibir mensajes JMS y de tratarlos por si 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. La otra interfaz a implementar es la ya conocida MessageListener, teniendo que sobreescribir el metodo 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 observar que solo se ha escrito codigo para el metodo onMessage(), es el que nos interesa.

Una vez compilada la clase, tenemos que hacer el deploy del EJB en el servidor de aplicaciones, yo he escogido la implementacion de refrencia de Sun, el J2EE, los pasos son los siguientes (previamente tenemos que tener iniciado el servidor J2EE, j2ee -verbose:

  • Ejecutar el deploytool: <ruta a j2ee>indeploytool
  • Cree una aplicación nueva, o añada un nuevo ejb a una aplicación que ya tuviese creada
  • En la ventana New Enterprise Bean Wizard dele un nombre a su ejb (MessageBean esta bien) y añada la clase compilada pulsando en el botón edit...
  • Pulse Next y en la ventana que le aparece, indique que es un Message Driven Bean y seleccione la clase que añadió anteriormente de la lista desplegable Enterprise Bean Class
  • Pulse Next e indique que la persistencia será proporcionada por el bean, Bean Managed Persistence
  • Pulse Next, y marque la casilla Queue y seleccione en las listas desplegables, Cola, QueueConnectionFactory y AUTO_ACKNOWLEDGE.
  • Pulse Next varias veces hasta que llegue a la ventana de seguridad, aqui seleccione Use Caller ID, pulse Next y Finish. Ya ha añadido un MDB al servidor.
  • Solo queda hacer el deploy, pulse tools-deploy. No necesita que le devuelva un jar de cliente.

Si todo ha ido bien, ya tiene su MDB dispuesto a recibir mensajes. Para esto ejecute una de las primeras clases que hemos programado, EnviaCola, para enviar mensajes a la cola, y compruebe (en la consola donde ejecuto j2ee -verbose) que se muestran los mensajes recibidos.

Si en lugar de recibir mensajes de una cola, los quisiesemos recuperar de un asunto (con una suscripción) solo tenemos que indicarlo en el deploy.

Enlaces

Archivo zip con los fuentes de los ejemplos: ejemplos_jms.zip

Especificación de Java Message Service de Sun: http://java.sun.com/products/jms/jms1_0_2-spec.pdf

Libro sobre JMS de Richard Monson-Haefel: http://www.store.yahoo.com/titan-books/javmesser.html

Java Enterprise Edition, J2EE: http://java.sun.com/j2ee/

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.