Académique Documents
Professionnel Documents
Culture Documents
0
Parte 4: Message Driven Bean
<
ATENO: Este material contm algumas imagens retirardas da docomentao oficial da SUN e adaptadas para este material. As mesmas podem ser encontradas no site www.sun.com . O objetivo deste material recompilar uma srie de informaes existentes que possam ser utilizadas para o estudo da tecnologia EJB 3.0 pelo leitor. No final se listam as bibliografias utilizadas e sugerimos que as mesmas sejam utilizadas para aprofundar os conhecimentos nesta tecnologia.
Como podemos ver na figura acima, um cliente envia uma mensagem JMS para um destino e o container passa esta mensagem JMS para uma instncia do bean orientado a mensagens que tem se registrado como um receptor de mensagens para uma destinao particular. Por usar um pool de instncia de beans, o container capaz de manipular as mensagens que chegam de uma forma muito mais eficiente e aumenta a escalabilidade das operaes JMS. As instncias dos beans podem ser colocadas ou retiradas do pool dependendo das necessidades do container de atender as requisies. Os beans orientados a mensagens no possuem estado conversacional e portanto, so similares neste aspecto aos beans de sesso stateless. Isto no significa que estes beans no podem ter variveis de instncia, somente significa que as variveis de instncia que os beans possurem no podem ser usadas para guardar informaes de estado de um cliente particular porque no garantido que um mesmo bean atenda um mesmo cliente. Isto at certo ponto obvio porque o cliente no acessa diretamente um bean orientado a mensagens. Um exemplo interessante seria quando definimos uma pea de teatro como sendo o bean de sesso, os atores o bean de entidade, e poderamos definir os beans orientados a mensagens como aqueles scripts que ficam invisveis ao pblico, no havendo iterao direta. Apagar e acender as luzes quando o ator principal chega (pela primeira vez), seria anlogo a quando chegar uma mensagem ao destino JMS, o qual processa a mesma. Por assegurar que todas as instncias dos beans orientados a mensagens so idnticas, o container capaz de manipular um pequeno nmero de instncias no pool e ainda manipular uma grande carga de chamadas. Isto porque qualquer instncia livre pode ser usada para manipular qualquer requisio que chegar vindo de uma destinao especfica. A partir da criao do bean orientado a mensagens at a sua destruio, o container gerencia estes beans exclusivamente. Todos os servios oferecidos para os outros dois beans (sesso e entidade), tais como segurana, suporte a transao e concorrncia so, exceto as interfaces home e remote, providos. O container interage com os beans orientados a mensagens atravs de um conjunto de mtodos de callback que so implementados pelo bean orientado a mensagens. Estes mtodos so similares aos usados pelos beans de sesso e os beans de entidade. Estes mtodos avisam ao bean que determinados eventos ocorrem ou ocorreram. Um Message Driven Bean (MDB) , portanto, um EJB que permite que as aplicaes J2EE processem mensagens de modo assncrono. Age como um listener de mensagens Java Message Service (JMS), o qual similar a um ouvinte de eventos, a no ser pelo fato de que, ao invs de receber eventos, ele recebe mensagens. As mensagens podem ser emitidas por qualquer componente de J2EE - um cliente da aplicao, um outro EJB, ou um componente WEB -- ou por uma aplicao/sistema JMS que no usem a tecnologia J2EE. Os MDBs atualmente processam somente mensagens de JMS, mas no futuro podem ser usados para processar outros tipos de mensagens.
Escrevendo um MDB
Aqui vamos escrever um Message Driven Bean, porm antes em poucas linhas vamos entender alguns conceitos importantes para este estudo. Aplicaes que utilizam JMS so chamadas de JMS Clients, e o sistema de mensagens Clients que realiza o roteamento e entrega de mensagens chamado de JMS Provider Uma JMS Provider. Application um sistema composto por muitos JMS Clients e, geralmente, um JMS Provider. Um JMS Client que manda mensagens chamado de producer e um JMS Client que recebe producer, uma mensagem chamado de consumer. Um JMS Client pode ser ao mesmo tempo um consumer. producer e um consumer! Vamos agora ver um exemplo de Message Driven Bean:
package com.ejb.mdb; import javax.ejb.MessageDriven; import javax.jms.Message; import javax.jms.MessageListener; @MessageDriven public class ExemploMDB implements MessageListener { public void onMessage(Message message) { ... } } Cdigo 4-1: MDB simples
Observe acima que um MDB definido atravs do uso de anotaes. Nesta caso utilizada a anotao @javax.ejb.MessageDriven para anotar a classe com um MDB. Todo MDB implementa a interface javax.jms.MessageListener o que obrigar o desenvolvedor a implementar o mtodo onMessage() para tratar o recebimento de mensagens de um client producer. O cdigo a ser executado quando o MDB receber uma mensagem posto no mtodo onMessage(). Um EJB pode ser um consumidor de mensagens assncronas como o mostrado no exemplo acima ou pode ser um produtor de mensagens para que clientes JMS as recebam. Mais adiante mostraremos como fazer isto. Todo MDB deve estar escutando uma fila de mensagens (Queue ou estar inscrito Queue) para receber mensagens de um Topic opic.
Topic
Topic um modelo de mensagens JMS baseado na filosofia publish-and-subscribe. Este modelo tambm conhecido com um para muitos. Aqui uma mensagem JMS ser enviada para um Topic do container EJB e este ir imediatamente realizar um envio de uma cpia desta mensagem para todos aqueles clientes que estiverem inscritos para receber mensagens daquele tpico. Funciona semelhante a um broadcast de mensagens. Veja a figura abaixo:
Observe na figura acima que todos os MDBs que estiverem inscritos para receber mensagens do tpico iro receber. Abaixo um cdigo que cria um MDB para receber mensagens de um tpico:
Queue
Este modelo JMS baseado em fila (queue) permitir um cliente enviar mensagens para a fila de forma que outros possam consumir as mensagens da fila. Uma diferena importante com relao ao modelo topic que a mensagem de uma fila ser consumida apenas por um cliente e no distribuda para todos os inscritos como acontece com um topic. Abaixo veja como fica o modelo de um queue:
Observe que somente um MDB ir consumir a mensagem. Todas as mensagens enviadas por clientes ficam na Fila aguardando algum que as consuma. A deciso de qual modelo utilizar na sua aplicao ir depender em cada caso do que precisa ser representado com JMS. O modelo de Queue garante que somente um cliente ir processar a mensagem recebida. muitas vezes conhecido portanto com pier-to-pier (P2P).
try { InitialContext ctx = getInitialContext(); Topic topic = (Topic) ctx.lookup("topic/testTopic"); // Enviar mensagem para um TOPIC TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("TopicConnectionFactory"); TopicConnection connection = factory.createTopicConnection(); TopicSession session = connection.createTopicSession( false, QueueSession.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(topic); TextMessage textMsg = session.createTextMessage(); textMsg.setText("Ol clientes do topic! "); producer.send(textMsg); connection.start(); connection.close(); System.out.println("Mensagem enviada para topic: "+topic.getTopicName()+ " pelo client!");
Observe que o programa acima envia uma mensagem para um tpico de nome topic/testTopic do container EJB. Para realizar este envio so necessrios alguns objetos os quais so apresentados abaixo:
javax.jms.MessageProducer
Interface utilizada para representar um objeto com o qual possvel enviar mensagens para um determinado tpico. Observe que ao criar o MessageProducer passado o tpico correspondente.
javax.jms.TopicSession
Interface utilizada para representar a sesso do cliente com o tpico no container EJB. Esta sesso semelhante as sesses web que estamos acostumados.
javax.jms.TextMessage
Mensagem textual criada atravs de um objeto session e que pode ser populada com strings para ser enviada pelo MessageProducer para o topic.
javax.jms.Topic
Representa o topico retornado pelo lookup no JNDI ENC.
javax.jms.TopicConnection
Conexo com o topic do container. Esta conexo utilizada para criar a sesso com o tpico.
javax.jms.TopicConnectionFactory
Fbrica de tpicos utilizada para criar TopicConnection. Esta fabrica de tpicos retornado atravs de um lookup no JNDI ENC do container.
@MessageDriven e @ActivationConfigProperty
Ao definir um Message Driven Bean com a anotao @MessageDrivern necessrio fornecer mais algumas informaes sobre este bean. O bean que esta sendo definido precisa saber se ser um listener de um Topic ou Queue. Isto feito atravs da anotao @ActivationConfigProperty. Abaixo um cdigo que mostra como isto pode ser feito.
package com.ejb.mdb; import import import import import import javax.ejb.ActivationConfigProperty; javax.ejb.MessageDriven; javax.jms.JMSException; javax.jms.Message; javax.jms.MessageListener; javax.jms.TextMessage;
@MessageDriven( activationConfig = {@ActivationConfigProperty(propertyName="acknowledgeMode", propertyValue="Auto-acknowledge"), @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"), @ActivationConfigProperty(propertyName="destination", propertyValue="topic/testTopic"), @ActivationConfigProperty(propertyName= connectionFactoryJndiName", propertyValue="TopicConnectionFactory") } ) public class MDBTopicSample implements MessageListener {
public void onMessage(Message message) { try { System.out.println("Message Driven Bean-Topic-[ onMessage() ] ..."); TextMessage textMsg = (TextMessage)message; System.out.println("Message: "+ textMsg.getText() ); } catch (JMSException ex) { System.out.println("Erro ao pegar a mensagem: "+ex.getMessage() ); } } } Cdigo 4-3: EJB MDB tratando mensagens
Observe acima que o atributo activationConfig() de @MessageDriven recebe um array de anotaes @ActivationConfigProperty. Estas anotaes so um par de nome/valor que descrevem a configurao do MDB. Acknowledge Acknowledge mode utilizado pelos clientes que recebem a mensagem para comunicar o JMS provider de que a mensagem foi recebida e processada. Caso no seja comunicado o provider isto poder fazer com que o mesmo reenvie a mensagem fazendo assim com que o cliente receba duas ou mais vezes a mesma mensagem. Acknowledge mode aceita dois possveis valores: Auto-acknowledge e Dups-ok-acknowledge. AutoAuto-
acknowledge ir fazer com que o cliente mande o aviso de recebimento da mensagem para o provider logo aps o MDB ter recebido a mensagem para processar. Dups-ok-acknowledge Dups-okfar com que o container no precise mandar o aviso de recebimento imediantamente aps receber a mensagem. O aviso poder ser enviado a qualquer momento aps ter dado ao MDB a mensagem. Isto pode faze com que o provider assuma que a mensagem no foi recebida e a envie novamente. O uso de Dups-ok-acknowledge faz com que a rede seja poupada e tenha um menor trafego. Mas na prtica o consumo de rede to pequeno tornando o Dups-ok-acknowledge no muito utilizado. Destination type , como o prprio nome j sugere o tipo de JMS de destino. Neste caso podemos espeficicar se ser topic ou queue com os respectivos valores: javax.jms.Topic ou javax.jms.Queue. Destination representa o nome do topic ou queue registrado no container EJB. No exemplo acima utilizamos um topic j registrado no JBoss, o topic/testTopic. Connection Factory Jndi Name especifica o nome da fbrica que ser utilizada para a criao de topic ou queue. No exemplo acima utilizamos um connection factory para topic chamado TopicConnectionFactory. Outro @ActivationConfigProperty que pode ser utilizado em alguns casos o Subscription Durability Este atributo utilizado com topic e serve para dizer se as Subscription Durability. mensagens enviadas para o tpico sero durveis ou no. Em caso de serem durveis (Durable) se o EJB contatiner sofre alguma falha como por exemplo reiniciar ou desconectar do JMS provider, as mensagens enviadas para o provider no sero perdidas pois sero salvas pelo JMS provider at que o EJB container volte a fncionar. Quando o container voltar e reconectar ao provider ento as mensagens so enviadas para o container e este as envia para os MDBs. A outra possibilidade que temos no armazenar as mensagens como mensagens durveis (NonDurable). Isto deixa levemetne mais rpido o JMS provider, mas diminui a sua confiabilidade. Veja abaixo como definir este atributo.
@MessageDriven( activationConfig = { @ActivationConfigProperty( propertyName="subscriptionDurability", propertyValue="Durable" ) } ) public class MDBTopicSample implements MessageListener { ... } Cdigo 4-4: Configurando um MDB com anotaes
Observe no cdigo acima como um EJB pode receber atravs de anotaes uma referncia para o TopicConnectionFactory e para o Topic. Utilizando a anotao @javax.annotation.Resource, injetamos no EJB as referncias. O cdigo que temos dentro do MDB um mtodo definido nas interfaces deste EJB para que ao ser chamado remotamente possa produzir uma mensagem e enviar a mesma ao topic. Como invertemos os papis e criamos acima um EJB para produzir uma mensagem e enviar ao topic, vamos agora ver como podemos escrever um cliente que standalone que atravs de JMS possa consumir mensagens de um topic. Abaixo o cdigo que realiza esta tarefa:
public class JMSTopicClient implements MessageListener { public JMSTopicClient() { try { InitialContext ctx = getInitialContext(); Topic topic = (Topic)ctx.lookup("topic/testTopic"); TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("TopicConnectionFactory"); TopicConnection connect = factory.createTopicConnection(); TopicSession session = connect.createTopicSession( false, Session.AUTO_ACKNOWLEDGE ); MessageConsumer consumer = session.createConsumer( topic ); consumer.setMessageListener(this); connect.start(); } catch (Exception ex) { ex.printStackTrace(); } }
public void onMessage(Message message) { try { TextMessage textMsg = (TextMessage)message; String text = textMsg.getText(); System.out.println("Mensagem recebida: "+ text ); } catch (JMSException ex) { ex.printStackTrace(); } } } Cdigo 4-6: Cliente EJB MDB
A classe acima define um cliente que pode ser executado em outra JVM que no dentro de um EJB Container. Observe que esta classe implementa a interface MessageListener o que far com que na classe tenhamos mtodo onMessage(Message message) e ento quando uma mensagem chegar o mesmo ser executado. Observe que atravs da sesso criamos um MessageConsumer que um objeto para registrar um listener (assim como fazamos no curso de Java Avanado para as interfaces grficas) que tratar com o mtodo onMessage() o recebimento da mensagem. Lembre-se que podemos ter vrios clientes consumidores registrados/inscritos a um topic.
try { InitialContext ctx = getInitialContext(); Queue queue = (Queue) ctx.lookup("queue/MyQueue"); QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory"); QueueConnection connection = factory.createQueueConnection(); QueueSession session = connection.createQueueSession( false, QueueSession.AUTO_ACKNOWLEDGE); TextMessage msg = session.createTextMessage(" Ol fila queue! "); QueueSender sender = session.createSender(queue); sender.send(msg); connection.close(); System.out.println("Mensagem enviada para queue: "+queue.getQueueName()+ " pelo client!"); } catch (Exception ex) { ex.printStackTrace(); } } } Cdigo 4-7: Cliente standalone para queue
Observe que no cdigo acima feito um lookup na queue/MyQueue para ter acesso a fila e poder enviar mensagens.
Como um stateless session bean, um message-driven bean no nunca colocado no estado de passivo, e possui somente os estados mostradoa acima: no existente e pronto para receber mensagens.
@javax.annotation.PreDestroy.
No final do ciclo de vida, o container chama o mtodo anotado com A instncia do bean est ento pronta para ser coletada pelo garbage collector.
Abaixo mostramos um exemplo completo de um Message Driven Bean inscrito para um topic contendo os mtodos do ciclo de vida.
package com.ejb.mdb; import import import import import import javax.annotation.PostConstruct; javax.annotation.PreDestroy; javax.ejb.ActivationConfigProperty; javax.ejb.MessageDriven; javax.jms.Message; javax.jms.MessageListener;
@MessageDriven(mappedName = "jms/MDBCicloVida", activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/testTopic"), @ActivationConfigProperty(propertyName = "connectionFactoryJndiName", propertyValue = "TopicConnectionFactory") } ) public class MDBCicloVida implements MessageListener { public MDBCicloVida() { } public void onMessage(Message message) { System.out.println("onMessage() do MDBCicloVida executado!"); } // Mtodos do ciclo de vida @PostConstruct public void initialize() { System.out.println("MDB criado! @PostConstruct executado! "); } @PreDestroy public void exit() { System.out.println("MDB ser destruido! @PreDestroy executado! "); } } Cdigo 4-8: EJB MDB com ciclo de vida
@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/MyQueue"), @ActivationConfigProperty(propertyName = "connectionFactoryJndiName", propertyValue = "QueueConnectionFactory") } ) public class MDBQueueSample implements MessageListener { public void onMessage(Message message) { try { System.out.println("MDB - Queue - [ onMessage() ] ..."); TextMessage textMsg = (TextMessage)message; System.out.println("Message: "+ textMsg.getText() ); } catch (JMSException ex) { System.out.println("Erro ao pegar a mensagem: "+ex.getMessage() ); } } } Cdigo 4-9: EJB exemplo
O MDB acima um bean consumidor de mensagens da fila queue/MyQueue. Abaixo o cliente que pode enviar mensagens JMS para esta queue:
package com.jms.queue; import import import import import import import import import import import java.util.Properties; javax.jms.Queue; javax.jms.QueueConnection; javax.jms.QueueConnectionFactory; javax.jms.QueueSender; javax.jms.QueueSession; javax.jms.TextMessage; javax.naming.Context; javax.naming.InitialContext; javax.naming.NamingException; javax.swing.JOptionPane;
try { InitialContext ctx = getInitialContext(); Queue queue = (Queue) ctx.lookup("queue/MyQueue"); QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory"); QueueConnection connection = factory.createQueueConnection(); QueueSession session = connection.createQueueSession( false, QueueSession.AUTO_ACKNOWLEDGE); TextMessage msg = session.createTextMessage(" Ol fila queue! "); QueueSender sender = session.createSender(queue); sender.send(msg); connection.close(); System.out.println("Mensagem enviada para queue: "+queue.getQueueName()+ " pelo client!"); } catch (Exception ex) { ex.printStackTrace(); } } public static InitialContext getInitialContext() throws NamingException { Properties env = new Properties(); env.put(Context.SECURITY_PRINCIPAL, "guest" ); env.put(Context.SECURITY_CREDENTIALS, "guest" ); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory"); env.put(Context.PROVIDER_URL, "jnp://10.1.1.3:1099"); return new InitialContext(env); } } Cdigo 4-10: Cliente JMS standalone produtor
Na seqncia apresentamos um cliente standalone que ao invs de produzir mensagens JMS ser um consumidor de mensagens JMS.
public class JMSQueueReceiveClient implements MessageListener { public JMSQueueReceiveClient() { try { InitialContext ctx = getInitialContext(); QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("QueueConnectionFactory"); Queue queue = (Queue)ctx.lookup("queue/MyQueue"); QueueConnection connect = factory.createQueueConnection(); QueueSession session = connect.createQueueSession( false, Session.AUTO_ACKNOWLEDGE ); MessageConsumer consumer = session.createConsumer( queue ); consumer.setMessageListener(this); connect.start(); } catch (Exception ex) { ex.printStackTrace(); } }
public static void main(String[] args) throws Exception { JMSQueueReceiveClient client = new JMSQueueReceiveClient(); int i = 0; while(true) { Thread.sleep(10000); i++; System.out.println("["+i+"] Checando queue ..."); } }
public static InitialContext getInitialContext() throws NamingException { Properties env = new Properties(); env.put(Context.SECURITY_PRINCIPAL, "guest" ); env.put(Context.SECURITY_CREDENTIALS, "guest" ); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory"); env.put(Context.PROVIDER_URL, "jnp://10.1.1.3:1099"); return new InitialContext(env); }
public void onMessage(Message message) { try { TextMessage textMsg = (TextMessage)message; String text = textMsg.getText(); System.out.println("Mensagem recebida: "+ text ); } catch (JMSException ex) { ex.printStackTrace(); } } } Cdigo 4-11: Cliente JMS standalone consumidor
@MessageDriven( activationConfig = { @ActivationConfigProperty(propertyName propertyValue @ActivationConfigProperty(propertyName propertyValue @ActivationConfigProperty(propertyName propertyValue @ActivationConfigProperty(propertyName = propertyValue = } = "acknowledgeMode", = "Auto-acknowledge"), = "destinationType", = "javax.jms.Topic"), = "destination", = "topic/testTopic"), "connectionFactoryJndiName", "TopicConnectionFactory")
) public class MDBTopicSample implements MessageListener { public void onMessage(Message message) { try { System.out.println("MDB - Topic - [ onMessage() ] ..."); TextMessage textMsg = (TextMessage)message; System.out.println("Message: "+ textMsg.getText() ); } catch (JMSException ex) { System.out.println("Erro ao pegar a mensagem: "+ex.getMessage() ); } } } Cdigo 4-12: MDB cliente para topic
public class JMSTopicSendClient { public static void main(String[] args) { try { InitialContext ctx = getInitialContext(); Topic topic = (Topic) ctx.lookup("topic/testTopic"); // Enviar mensagem para um TOPIC TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("TopicConnectionFactory"); TopicConnection connection = factory.createTopicConnection(); TopicSession session = connection.createTopicSession( false, TopicSession.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(topic); TextMessage textMsg = session.createTextMessage(); textMsg.setText("Ol fila topic! "); producer.send(textMsg); connection.start(); connection.close(); System.out.println("Mensagem enviada para topic: "+topic.getTopicName()+ " pelo client!"); } catch (Exception ex) { ex.printStackTrace(); } } public static InitialContext getInitialContext() throws NamingException { Properties env = new Properties(); env.put(Context.SECURITY_PRINCIPAL, "guest" ); env.put(Context.SECURITY_CREDENTIALS, "guest" ); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory"); env.put(Context.PROVIDER_URL, "jnp://10.1.1.3:1099"); return new InitialContext(env); } } Cdigo 4-13: Cliente standalone produtor para topic
public class JMSTopicReceiveClient implements MessageListener { public JMSTopicReceiveClient() { try { InitialContext ctx = getInitialContext(); Topic topic = (Topic)ctx.lookup("topic/testTopic"); TopicConnectionFactory factory = (TopicConnectionFactory) ctx.lookup("TopicConnectionFactory"); TopicConnection connect = factory.createTopicConnection(); TopicSession session = connect.createTopicSession( false, Session.AUTO_ACKNOWLEDGE ); MessageConsumer consumer = session.createConsumer( topic ); consumer.setMessageListener(this); connect.start(); } catch (Exception ex) { ex.printStackTrace(); } }
public static void main(String[] args) throws Exception { JMSTopicReceiveClient client = new JMSTopicReceiveClient(); int i = 0; while(true) { Thread.sleep(10000); i++; System.out.println("["+i+"] Checando topic ..."); } }
public static InitialContext getInitialContext() throws NamingException { Properties env = new Properties(); env.put(Context.SECURITY_PRINCIPAL, "guest" ); env.put(Context.SECURITY_CREDENTIALS, "guest" ); env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.JndiLoginInitialContextFactory"); env.put(Context.PROVIDER_URL, "jnp://10.1.1.3:1099"); return new InitialContext(env); }
public void onMessage(Message message) { try { TextMessage textMsg = (TextMessage)message; String text = textMsg.getText(); System.out.println("Mensagem recebida: "+ text ); } catch (JMSException ex) { ex.printStackTrace(); } } } Cdigo 4-14: Cliente standalone consumidor para topic
Bibliografia
1 - BURKE, Bill and MONSON-HAEFEL, Richard. "Enterprise JavaBeans 3.0". O'Reilly. 5 ed. 2006. 760 p. 2 - JENDROCK, Eric et al. "The Java EE 5 Tutorial". (http://java.sun.com/javaee/5/docs /tutorial/doc) Consultado em 16/04/2007. 3 - JBoss Web Site: http://labs.jboss.com/portal/jbossejb3. Consultado em 15/04/2007.