JMS. Java Message Service



Documentos relacionados
Message Driven Beans. Apresentação. Introdução Implementação de MDBs Deployment no JBoss Java Messaging Service Exemplo

A interface de uma mensagem é extremamente flexível e permite várias formas de customização de conteúdo. Figura 1 - Tipos de Mensagens JMS

Enterprise Java Beans

Java Message Service (JMS)

UTILIZAÇÃO DA TECNOLOGIA ENTERPRISE JAVABEANS NO DESENVOLVIMENTO DE APLICAÇÕES DISTRÍBUIDAS

ENTERPRISE JAVABEANS 3. Msc. Daniele Carvalho Oliveira

UNIVERSIDADE. Sistemas Distribuídos

Como criar um EJB. Criando um projeto EJB com um cliente WEB no Eclipse

Java 2 Enterprise Edition Fundamentos básicos de Transações

PadrãoIX. Módulo II JAVA. Marcio de Carvalho Victorino. Servlets A,L,F,M

J530 - Enterprise JavaBeans. Message-driven Beans. argonavis.com.br. Helder da Rocha

Sistemas Distribuídos na WEB (Plataformas para Aplicações Distribuídas) Sumário. Java 2 Enterprise Edition. J2EE (Java 2 Enterprise Edition)

TDC2012. EJB simples e descomplicado, na prática. Slide 1

Considerações no Projeto de Sistemas Cliente/Servidor

Serviço de Transação. Transação - Conceitos

Comunicação entre Processos

3 Um Framework Orientado a Aspectos para Monitoramento e Análise de Processos de Negócio

Enterprise Java Bean. Enterprise JavaBeans

UNIDADE IV ENTERPRISE JAVABEANS

EJB. Session Beans. J2EE (C. Geyer) Introdução a SessionBean 1

Prof. Fellipe Araújo Aleixo

Laboratório de Computação VI JAVA IDL. Fabricio Aparecido Breve

Programação de Computadores - I. Profª Beatriz Profº Israel

Message Oriented Middleware (MOM)

Web Technologies. Tópicos da apresentação

Sistemas Distribuídos RPC x RMI. Edeyson Andrade Gomes



Enterprise Java Beans

UNIVERSIDADE. Sistemas Distribuídos

Java. Marcio de Carvalho Victorino

UFG - Instituto de Informática

Sistemas Distribuídos

Sistemas Distribuídos Capítulos 3 e 4 - Aula 4

Integrando Java com Banco de Dados

Programação Orientada a Objetos JDBC Java Database Connectivity

Laboratório de Banco de Dados Aula 1 Acesso a Banco de Dados. Prof. Josenildo Silva jcsilva@ifma.edu.br

UFG - Instituto de Informática

Programação distribuída e paralela (C. Geyer) RPC 1

Tutorial JMS com ActiveMQ Nível: Introdutório Autor: José Damico IBM Data: 26 de novembro de 2006

Aula 1 Acesso a Banco de Dados

Comunicação em Sistemas Distribuídos. Conceitos: Paradigma C/S. Conceitos: Paradigma C/S. Paradigma Cliente/Servidor

J2EE. J2EE - Surgimento

3 SCS: Sistema de Componentes de Software

1.6. Tratamento de Exceções

Bancos de dados distribuídos Prof. Tiago Eugenio de Melo

(UFF) JDBC (I) TEPIS II

INTEGRADOR DE MENSAGENS CORPORATIVAS PARA UMA INFRA-ESTRUTURA DE ELETRONIC DATA INTERCHANGE (EDI)

Stateful Session Beans

Sistemas Distribuídos

Parte I. Demoiselle Mail

REDES DE COMPUTADORES

J533 - Minicurso. Helder da Rocha (helder@acm.org)

Projeto de Software Orientado a Objeto

Guia de Fatores de Qualidade de OO e Java

Descrição. Implementação. Departamento de Informática e Estatística Universidade Federal de Santa Catarina LAB 4 Transferência de Arquivos

Especialização em desenvolvimento para web com interfaces ricas. Tratamento de exceções em Java Prof. Fabrízzio A. A. M. N. Soares

Framework. Marcos Paulo de Souza Brito João Paulo Raittes

Orientação a Objetos

Fundamentos da Plataforma Java EE. Prof. Fellipe Aleixo

4. Qual seria o impacto da escolha de uma chave que possua letras repetidas em uma cifra de transposição?

Programação com Acesso a Banco de Dados

Invocação de Métodos Remotos

Linguagem de Programação JAVA. Técnico em Informática Professora Michelle Nery

4 - Padrões da Camada de Integração. Introdução

Introdução ao PHP. Prof. Késsia Marchi

Mini-curso Gratuito Globalcode Slide 1

CAMADA DE TRANSPORTE

Documentação Usando o Javadoc

FBV - Linguagem de Programação II. Um pouco sobre Java

Exercícios de Revisão Java Básico

Sistemas Distribuídos

Informática UFRGS. Programação com Objetos Distribuídos (C. Geyer) C# Remote V0 1

Entendendo como funciona o NAT

Sistemas Distribuídos. Coulouris Capítulo 4

Acesso a Banco. Conexão em Java. Conexão em Java. Programação Orientada a Objetos Profa. Cristiane e Prof. Daniel

Comunicação Inter-Processos. Prof. Adriano Fiorese. Conceitos Iniciais

8. Outros tipos de Transação (Modo de Transação de Autoconfirmação e Modo Implícito)

Aula 2. Objetivos. Encapsulamento na linguagem Java; Utilizando a referência this.

JPA: Persistência padronizada em Java

Lista de Contas: Assinatura. Lista de Contas. Listas de Contas: Descrição. Listas de Contas: Descrição. Listas de Contas: Descrição

Invocação de Métodos Remotos RMI (Remote Method Invocation)

Manual do Desenvolvedor Criptografia de Arquivos do WebTA

Sistemas Distribuídos. Professora: Ana Paula Couto DCC 064

Leonardo Gresta Paulino Murta

Programação por Objectos. Java

SISTEMAS DISTRIBUÍDOS

Sistemas Distribuídos

Tópicos em Sistemas Distribuídos. Modelos de Comunicação

EJB 3.1: A Community Update

Licenciatura em Engenharia Informática Sistemas Distribuídos I 2ª chamada, 6 de Julho de º Semestre, 2004/2005

Manipulação de Banco de Dados com Java. Ms. Bruno Crestani Calegaro Maio/ 2015

UFG - Instituto de Informática

MIDDLEWARE Aplicativos RMI, RPC e eventos Camadas Protocolo Requesição-Respostal Middleware Representação Externa dos Dados Sistemas Operacionais

Java 2 Enterprise Edition Session Beans

3. Explique o motivo pelo qual os protocolos UDP e TCP acrescentam a informação das portas (TSAP) de origem e de destino em seu cabeçalho.

ECD1200 Equipamento de Consulta de Dados KIT DE DESENVOLVIMENTO

Transcrição:

JMS

Autoria Autoria Fábio Cecin (1a versão) Versão V3.2, junho de 2013 C. Geyer

Referências Referências: The JMS Tutorial após versão 1.4 do JEE em capítulo do tutorial JEE da Sun v.1.5 (JEE): até v. 1.3: http://java.sun.com/javaee/5/docs/tutorial/doc/ http://java.sun.com/products/jms/tutorial/ Documentação (javadoc) do pacote JMS: http://java.sun.com/javaee/5/docs/api Dica: utilizar estes documentos como referência de programação para os exercícios.

Referências Referências: The JMS Tutorial Após versão 1.4 do JEE Em capítulos do tutorial JEE da Sun v.1.6 (JEE): Caps. 47 e 48 http://docs.oracle.com/javaee/6/tutorial/doc/

Referências Referências: The JMS Tutorial Até v. 1.3: http://docs.oracle.com/javaee/1.3/jms/tutorial/ http://java.sun.com/products/jms/tutorial/ Em 2012 desvia para: http://www.oracle.com/technetwork/java/jms/ index.html

Referências Referências: Especificação http://www.oracle.com/technetwork/java/ docs-136352.html

Súmula Súmula Visão Geral JMS Arquitetura Modelo de Programação Mecanismos de Confiabilidade Integração com EJB Enterprise JavaBeans Message-Driven Beans

Visão geral Visão Geral JMS é uma API padrão da plataforma JEE que dá acesso a serviços de messaging. Messaging pode ser entendido como troca de mensagens, similar ao sistema de correio eletrônico. JMS é uma API mais um serviço para troca de mensagens entre componentes de software distribuídos oferecendo diversas funcionalidades inexistentes em outros pacotes (bibliotecas, mws, protocolos, ) Recepção Assíncrona (também) e Confiável similar à programação orientada a eventos.

Visão geral Visão Geral JMS foi originalmente desenvolvido para a integração com MOMs (Message-Oriented Middleware) Por exemplo, MQSeries da IBM Permitiria comunicação entre componentes Java e não-java Mas pode ser usado atualmente para integração com Sistemas de Informação (EIS: Enterprise Information Systems) existentes A partir da versão 1.3 do padrão JEE, a API JMS tornou-se uma solução completa, independente, para aplicações de messaging. Procura ser ao mesmo tempo: simples e flexível, com diversas opções

Visão Geral Vantagens de JMS Especialmente sobre alternativas mais fortemente acopladas (RMI ): Fácil substituição: componentes não dependem da interface de outros componentes Componentes que trocam mensagens via JMS não precisam se conhecer Comunicação entre dois componentes não requer que ambos estejam operacionais para que a comunicação aconteça É possível enviar uma mensagem e continuar a execução de forma assíncrona

Visão Geral Vantagens de JMS Diversas opções de sincronização no recebimento time-out síncrona e assíncrona 2 grandes modelos ponto a ponto publicador-assinante (publish-subscribe)

Visão Geral JMS versões Segundo artigos da Oracle v1.1: 2002 v2.0: abril 2013 Ou segundo wikipedia JMS 1.0.2b (June 25, 2001) JMS 1.1 (March 18, 2002) JMS 2.0 (May 21 2013)

Visão Geral JMS implementações Em http://en.wikipedia.org/wiki/java_message_service ActiveMQ Apache Apache Qpid, using AMQP http://qpid.apache.org Oracle Weblogic (part of the Oracle Fusion Middleware Fusion Middleware suite) and Oracle AQ from Oracle Corporation EMS from TIBCO FFMQ, GNU LGPL licensed

Visão Geral JMS implementações JBoss Messaging and HornetQ from Jboss JORAM from the OW2 Consortium Open Message Queue from Oracle OpenJMS from The OpenJMS Group Solace JMS from Solace systems RabbitMQ by Rabbit Technologies Ltd., acquired by SpringSource

Visão Geral JMS implementações SAP Process Integration ESB SonicMQ from Progress Software StormMQ, using AMQP SwiftMQ Tervela

JMS implementações Visão Geral Ultra Messaging from 29 West (acquired by Informatica) webmethods from Software AG WebSphere Application Server from IBM which provides an inbuilt default messaging provider known as the Service Integration Bus (SIBus), or which can connect to WebSphere MQ as a JMS provider "Choosing a messaging system: WebSphere MQ vs. the WebSphere Application Server Service Integration Bus http://www.ibm.com/developerworks/websphere/ library/techarticles/1109_wallis/1109_wallis.html work=ibm developerworks WebSphere MQ (formerly MQSeries) from[ibm

Visão Geral JMS - características funcionais em JEE: EJBs, clientes e componentes web podem consumir mensagens JMS de forma síncrona (recepção) Permite interação com um novo ( faz tempo ) tipo de bean, o message-driven bean: um EJB que consome mensagens JMS de forma assíncrona. Envio e recebimento de mensagens JMS podem participar de transações distribuídas.

Arquitetura JMS Arquitetura JMS Administrative Tool; Cliente JMS Provedor JMS

Arquitetura JMS Provedor de Serviço JMS: Implementa as interfaces do JMS Oferece recursos administrativos e de controle JEE deve oferecer um provedor JMS Clientes JMS: Componentes escritos em Java Consomem e produzem mensagens Arquitetura JMS Todo componente de uma aplicação JEE pode ser cliente JM

Arquitetura JMS Arquitetura JMS Ferramenta administrativa cria objetos administrativos em um serviço de nomes JNDI objetos são Connection Factories e Destinations, utilizados pelos clientes JMS.

Arquitetura JMS Um provedor de serviços JMS (JEE 1.3 e mais) suporta obrigatoriamente tanto o domínio de comunicação ponto-a-ponto quanto o de publicador-assinante. Ponto-a-ponto Publicador-assinante

Modelo (domaine) ponto-a-ponto abstrações filas (queues) de mensagens produtores de mensagens consumidores de mensagens cada mensagem é enviada a uma fila Modelo ponto-a-ponto fila mantém mensagens até serem consumidas ou expiradas cada mensagem só tem um consumidor sem dependência de tempo entre produtor e consumidor consumidor pode consumir mensagem mesmo se não estivesse executando quando do envio da mensagem recebedor confirma recepção da mensagem

Modelo publicador-assinante Modelo publicador-assinante abstrações tópicos (topics) publicadores de mensagens assinantes de mensagens clientes publicadores enviam (publicam) mensagens a um tópico (topic) assinantes se inscrevem como interessados em um tópico o sistema se encarrega de distribuir as mensagens de um tópico aos assinantes desse tópico mensagens são mantidas até que todos os assinantes atuais as recebam

Modelo publicador-assinante Modelo publicador-assinante uma mensagem pode ter vários consumidores (assinantes) há dependência de tempo entre publicador e assinante um assinante só pode consumir mensagens publicadas após a inscrição subscrições duráveis permitem contornar a dependência de tempo oferecem mais flexibilidade e confiabilidade (como as filas) mas preservam a relação n (> 1) consumidores para 1 mensagem

Modelos x Usos Quando usar cada modelo? ponto-a-ponto: use quando cada mensagem deve ser lida por 1 cliente publicador-assinante use quando cada mensagem pode ser lida por zero, 1 ou vários clientes

Interfaces comuns Interfaces comuns envio e recepção de mensagens com o mesmo código seja fila (ponto-a-ponto) ou topic (assinante) as destinações indicarão se fila ou topic as destinações podem ser definidas dinamicamente

Consumo de mensagens Consumo de mensagens Síncrono cliente deve executar o método receive o método receive bloqueia até: uma mensagem chegar ou se houver um time-out Assíncrona cliente registra um message-listener a um consumidor semelhante a um event-listener a cada nova mensagem que chega ao destino o sistema chama o método onmessage esse método processa a mensagem

Modelo de Programação JMS Modelo JMS: Entidades Administrativas: - Fábricas de Conexões - Destinos Entidades de Programação: - Conexão - Sessão - Mensagem - Produtor - Consumidor

Modelo de Programação JMS Fábricas de conexões e destinos São criados e modificados em ferramentas administrativas, em contraste com criação via clientes JMS. O objetivo é manter a portabilidade da API, ao encapsular informações específicas de conexão e de endereçamento nestes objetos. Cada fornecedor JEE Implementa suas próprias ferramentas administrativas. Sun JEE: j2eeadmin (/j2ee/bin) (versão 1.3) Clientes JMS acessam esses objetos através de interfaces padronizadas Usualmente via injeção de recursos (anotação)

Modelo de Programação JMS Fábrica de conexões (connection factory): É o objeto utilizado pelo cliente JMS para criar uma conexão com um serviço JMS. Uma instalação de JMS Deve fornecer pelo menos duas fábricas (nomes JNDI): QueueConnectionFactory (ponto-a-ponto) TopicConnectionFactory (publicador-assinante) Há ainda a fábrica geral: ConnectionFactory J2EE (C. Geyer)

Modelo de Programação JMS Exemplo: Obtendo uma Connection Factory em uma classe cliente @Resource(mappedName = "jms/connectionfactory") private static ConnectionFactory connectionfactory; @Resource(lookup = "jms/connectionfactory") private static ConnectionFactory connectionfactory;

Modelo de Programação JMS Destino (Destination): Um objeto que o cliente JMS usa como alvo das mensagens que produz e fonte das mensagens que consome. Em comunicação ponto-a-ponto um destino é chamado fila (queue) Em comunicação publicador-assinante um destino é chamado tópico (topic). Uma aplicação JMS Pode utilizar quantas filas e/ou tópicos forem necessários.

Modelo de Programação JMS Destino (Destination): Objetos filas e tópicos injetados no programa só podem ser usados como filas ou tópicos Objetos Destinations Para desenvolver componentes que manipulem filas e tópicos com o mesmo código se pode usar objetos Destinations O comportamento de um programa é determinado pelo tipo de destino (fila ou tópico) E não do tipo de factory

Modelo de Programação JMS JEE Sun Criando destinos (filas e tópicos): j2eeadmin -addjmsdestination <nome JNDI da fila> queue j2eeadmin -addjmsdestination <nome JNDI do tópico> topic obs.: válido para versão 1.3 (revisar nas seguintes)

Modelo de Programação JMS Visão geral de codificando um cliente JMS : Obter ConnectionFactory e Destinations via @resource na classe cliente Usar factory para criar uma Connection com o provedor JMS Usar Connection para criar uma ou mais Sessions Usar uma Session com os Destinations para criar produtores e consumidores Habilitar a Connection (método start) para iniciar a entrega de Messages no cliente consumidor Criar uma mensagem usando método específico (conforme tipo da mensagem) de Session Enviar mensagem com método send do produtor Receber mensagem com método receive do consumidor

Modelo de Programação JMS JEE Sun Obtendo um destino no cliente, após criação: @Resource(mappedName = "jms/queue") private static Queue queue @Resource(mappedName = "jms/topic" private static Topic topic; @Resource(lookup = "jms/queue") private static Queue queue; @Resource(lookup = "jms/topic") private static Topic topic;

Modelo de Programação JMS Conexões (Connections): Conexão é um canal entre o cliente e o provedor de serviço JMS Após criado e obtido (@resource) um objeto fábrica de conexões, é possível criar conexões a partir do mesmo: QueueConnection myqueuecon = myqueuefact.createqueueconnection(); TopicConnection mytopiccon = mytopicfact.createtopicconnection(); Connection connection = connectionfactory.createconnection() A criação geral (Connection) pode ser usada para queue e topic queue e topic serão indicados na criação de produtores e consumidores

Modelo de Programação JMS Conexões Podem ser (re)iniciadas e suspensas após criação. Não há recebimento de mensagens enquanto a conexão está suspensa: myqueuecon.start(); /* (re)inicia */ myqueuecon.stop(); /* suspende */ connection.start(); connection.stop(); É necessário fechar conexões após o uso: myqueuecon.close(); connection.close();

Modelo de Programação JMS Resumo de codificando um cliente JMS : Obter ConnectionFactory e Destinations via @resource na classe cliente Usar factory para criar uma Connection com o provedor JMS Habilitar a Connection (método start) para iniciar a entrega de Messages no cliente consumidor Usar Connection para criar uma ou mais Sessions Usar uma Session com os Destinations para criar produtores e consumidores Criar uma mensagem usando método específico (conforme tipo da mensagem) de Session Enviar mensagem com método send do produtor Receber mensagem com método receive do consumidor

Modelo de Programação JMS Sessão (Session): Uma sessão representa um contexto para uma thread produzir e consumir mensagens. Também prove um contexto de transação para um conjunto de sends e receives

Modelo de Programação JMS Sessão (Session): A partir de uma conexão é possível criar sessões (sessions): QueueSession myqueuesession = myqueuecon.createqueuesession(false, Session.AUTO_ACKNOWLEDGE); Arg. 1: sessão sem semântica de transação. Arg. 2: confirmação automática de recebimento de mensagens pela sessão. Session session = connection.createsession( false, Session.AUTO_ACKNOWLEDGE);

Modelo de Programação JMS Resumo de codificando um cliente JMS : Obter ConnectionFactory e Destinations via @resource na classe cliente Usar factory para criar uma Connection com o provedor JMS Habilitar a Connection (método start) para iniciar a entrega de Messages no cliente consumidor Usar Connection para criar uma ou mais Sessions Usar uma Session com os Destinations para criar produtores e consumidores Criar uma mensagem usando método específico (conforme tipo da mensagem) de Session Enviar mensagem com método send do produtor Receber mensagem com método receive do consumidor

Modelo de Programação JMS Produtor de mensagens: É um objeto criado por uma sessão Utilizado para enviar mensagens para um destino especificado. Argumento da criação do produtor Há 3 tipos de interfaces conforme o tipo de destino Geral: interface Producer Para filas: interface QueueSender Para tópicos: interface TopicPublisher

Modelo de Programação JMS Exemplo de produtor Destination dest = queue ou topic;... Producer producer = session.createproducer(dest /*destino*/ ); Message mymessage = /* cria mensagem */ producer.send( mymessage );

Modelo de Programação JMS Produtor de mensagens: É possível não especificar o destino (null) Nesse caso o destino será especificado pelo método de envio (send)

Consumidor de mensagens: Modelo de Programação JMS Objeto criado por uma sessão para recebimento de mensagens enviadas a um destino especificado. Um cliente JMS utiliza um consumidor de mensagens para registrar interesse por certos destinos hospedados em um provedor JMS. O provedor de serviço JMS se encarrega de transferir as mensagens de um destino para os consumidores registrados neste destino. Antes do 1o receive, é necessário ativar a recepção via o método start da sessão

Modelo de Programação JMS Consumidor de mensagens: Geral: interface Consumer Para filas: interface QueueReceiver Para tópicos: interface TopicSubscriber Exemplo com consumo síncrono: Consumer consumer = session.createconsumer(dest); Message m = consumer.receive( 1000 ); receive ( ) parâmetro opcional timeout em milisegundos.

Modelo de Programação JMS Resumo de codificando um cliente JMS : Obter ConnectionFactory e Destinations via @resource na classe cliente Usar factory para criar uma Connection com o provedor JMS Usar Connection para criar uma ou mais Sessions Habilitar a Connection (método start) para iniciar a entrega de Messages no cliente consumidor Usar uma Session com os Destinations para criar produtores e consumidores Criar uma mensagem usando método específico (conforme tipo da mensagem) de Session Enviar mensagem com método send do produtor Receber mensagem com método receive do consumidor

Modelo de Programação JMS Mensagem (Message): Objeto que representa uma mensagem Formato permitiria uso de mensagens por aplicações não JMS Deve ser criado por uma sessão através de interface específica

Modelo de Programação JMS Mensagem (Message): Possui três partes: Cabeçalho (header): possui campos pré-definidos que devem ser preenchidos pela aplicação ou pela implementação JMS. tipo, destino, prioridade, time-stamp,... Propriedades (properties): espaço para um header opcional, mantido pela aplicação. Corpo (body): opcional.

Modelo de Programação JMS Tipos de mensagens (corpo): TextMessage: uma String BytesMessage: uma sequência de bytes StreamMessage: um stream de tipos primitivos Java (int, char, byte[], String...) ObjectMessage: objeto Java serializado Message: mensagem sem corpo

Modelo de Programação JMS Criando e enviando uma mensagem de texto: TextMessage message = session.createtextmessage(); message.settext( minha mensagem ); producer.send(message); Consumindo a mensagem: Message m = consumer.receive(); if (m instanceof TextMessage) { TextMessage message = (TextMessage)m; System.out.println( Mensagem chegou: + message.gettext() ); } else { /* erro: não recebe outro tipo de mensagem */ }

Modelo de Programação JMS Message listeners: Uma classe qualquer da aplicação pode atuar como consumidora assíncrona de mensagens ao implementar a interface MessageListener, do padrão JMS. Esta interface especifica o método: void onmessage( Message ) onde Message é a mensagem de interesse que deve ser processada pela classe. Esse método substitui o receive da recepção síncrona

Modelo de Programação JMS Message listeners: A classe listener deve ser registrada junto a um consumidor (Consumer ou QueueReceiver ou TopicSubscriber) através do método setmessagelistener( ) (do consumidor), para receber as mensagens. Exemplo: mytopicsubscriber.setmessagelistener( mytopiclistener ); Onde mytopiclistener é instância de classe que implementa a interface MessageListener. E mytopicsubscriber é um consumidor

Modelo de Programação JMS Message listeners: A entrega de mensagens também deve ser ativada pelo método start da sessão Um listener específico pode receber mensagens de ambos os tipos O tipo é definido pelo consumidor ao qual o listener registrado Vários listener podem estar registrados em uma sessão Os respectivos consumidores foram criados nessa sessão Nesse caso a execução de todos os listener é serializada Em JEE/EJB, um message drive bean é um caso especial de listener

Modelo de Programação JMS Filtro de mensagens: É possível filtrar mensagens em recepção Um seletor usa uma sintaxe baseada em SQL A seleção só pode ser feita sobre atributos das partes cabeçalho e propriedades da mensagem Não sobre atributos da 3a parte (aplicação)

Modelo de Programação JMS Exceções: JMS possui uma hierarquia de exceções, cuja raiz é JMSException. Portanto, é possível utilizar um tratador genérico para qualquer exceção JMS: try {... } catch (JMSException ex) {... }

Modelo de Programação JMS Resumo de codificando um cliente JMS : Obter ConnectionFactory e Destinations via @resource na classe cliente Usar factory para criar uma Connection com o provedor JMS Usar Connection para criar uma ou mais Sessions Usar uma Session com os Destinations para criar produtores e consumidores Habilitar a Connection (método start) para iniciar a entrega de Messages no cliente consumidor Criar uma mensagem usando método específico (conforme tipo da mensagem) de Session Enviar mensagem com método send do produtor Receber mensagem com método receive do consumidor

Confiabilidade JMS Confiabilidade JMS JMS possui vários mecanismos para aumento da robustez da aplicação: Nível de confirmação (acknowledgement) Persistência de mensagens Nível de prioridade da mensagem Mensagens com tempo de vida Criação de destinos temporários Assinaturas duráveis (durable subscriptions) Transações locais (local transactions)

Confiabilidade JMS Nível de confirmação (acknowledgement) é especificado na criação da fila ou tópico: Session.AUTO_ACKNOWLEDGE: mensagens automaticamente confirmadas. Session.CLIENT_ACKNOWLEDGE: cliente deve invocar o método acknowledge( ) da mensagem para confirmá-la. Session.DUPS_OK_ACKNOWLEDGE: idem a AUTO, porém pode resultar em entregas duplicadas de mensagens, com possível ganho em performance.

JMS 2.0 JMS 2.0 Objetivo principal Nova API simplified Permite códigos mais concisos, simples Tem todas funcionalidades da API anterior API 1.1 classic Continua válida sem prazo para deprecated

JMS 2.0 JMS 2.0 API simplified Novas interfaces: JMSContext, JMSProducer, and JMSConsumer JMSContext Substitui Connection e Session

JMS 2.0 JMS 2.0 API simplified JMSProducer Substitui MessageProducer Oferece manipulação da mensagem Opções de entrega Headers Properties Usando encadeamento de método (method chaining)

JMS 2.0 JMS 2.0 API simplified JMSConsumer Substitui MessageConsumer De modo similar à JMSProducer x MessageProducer

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Aplicação Versão classic Envio de mensagem de texto public void sendmessagejms11(connectionfactory connectionfactory, Queue queuestring text) { try { Connection connection = connectionfactory.createconnection(); try { Session session = connection.createsession(false, Session.AUTO_ACKNOWLEDGE);

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Aplicação Envio de mensagem de texto Versão classic } MessageProducer messageproducer = session.createproducer(queue); TextMessage textmessage = session.createtextmessage(text); messageproducer.send(textmessage); } finally { connection.close(); } } catch (JMSException ex) { // handle exception (details omitted) }

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Versão simplified public void sendmessagejms20(connectionfactory connectionfactory, Queue queue, String text) { try (JMSContext context = connectionfactory.createcontext();) { context.createproducer().send(queue, text); } catch (JMSRuntimeException ex) { // handle exception (details omitted) } }

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Diferenças Simplified cria um único objeto Context E não 2: Connection e Session Simplified tem chamada de close implícita Opções de sessão Simplified: há uma opção default false e Session.AUTO_ACKNOWLEDGE sem transação e confirmação automática de mensagens Outras opções: um (1) único parâmetro

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Diferenças Mensagens texto (text): conteúdo passado como argumento do método send processamento de exceções mais simples Exceção JMSRuntimeException

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Aplicação Recepção síncrona de mensagem de texto Diferenças similares às do envio

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Versão classic public String receivemessagejms11(connectionfactory connectionfactory,queue queue) { String body=null; try { Connection connection = connectionfactory.createconnection(); try { Session session = connection.createsession(false, Session.AUTO_ACKNOWLEDGE); MessageConsumer messageconsumer = session.createconsumer(queue); connection.start();

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Versão classic (cont.) } TextMessage textmessage = (TextMessage) messageconsumer.receive(); body = textmessage.gettext(); } finally { connection.close(); } } catch (JMSException ex) { // handle exception (details omitted) } return body;

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Versão simplified (cont.) public String receivemessagejms20( ConnectionFactory connectionfactory,queue queue) { String body=null; try (JMSContext context = connectionfactory.createcontext() { JMSConsumer consumer = session.createconsumer(queue); body = consumer.receivebody(string.class); } } catch (JMSRuntimeException ex) { // handle exception (details omitted) } return body;

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Diferenças Simplified cria um único objeto Context E não 2: Connection e Session Simplified tem chamada de close implícita Opções de sessão Simplified: há uma opção default false e Session.AUTO_ACKNOWLEDGE

JMS 2.0 JMS 2.0 Exemplo comparando simplified x classic Diferenças Não é necessário ativar a recepção (método start) Mensagens texto (text): Recupera texto (corpo da mensagem) com receive especial (sem uso de métodos adicionais) receivebody(string.class)

Resumo JMS Resumo JMS é uma especificação de serviços e API para troca de mensagens Arquitetura Clientes Ferramentas Provedor (serviço) Modos Filas Tópicos (publish/subscribe)

Resumo JMS Resumo API Factories Destinos Connections Sessions Producers e Consumers Messages Diversas funcionalidades como Semânticas variadas de sincronização Time-outs Maior confiabilidade

Fim Parcial

Opções de Confiabilidade

Confiabilidade JMS Persistência de mensagens: DeliveryMode.PERSISTENT: instrui o provedor de serviço JMS a tomar cuidado extra com esta mensagem, para que ela não seja perdida em caso de falhas no serviço. DeliveryMode.NON_PERSISTENT Esta opção pode ser especificada a cada envio de mensagem (nos métodos send( ) e publish( ) dos produtores), Ou especificada no produtor: myproducer.setdeliverymode( <modo> );

Confiabilidade JMS Nível de prioridade da mensagem: Entre 0 e 9 (default=4). O provedor JMS tenta entregar mensagens de maior prioridade primeiro. Pode ser especificado por envio de mensagem: mytopicpublisher.publish(message, DeliveryMode.NON_PERSISTENT, 3); // 3 é a prioridade Pode ser especificado no produtor: myproducer.setpriority( 3 );

Confiabilidade JMS Mensagens com tempo de vida Por exemplo, para se criar mensagens com tempo de vida de 16 segundos: mytopicpublisher.publish(message, DeliveryMode.NON_PERSISTENT, 3, 16000); myproducer.settimetolive( 16000 ); Por default, mensagens não expiram.

Confiabilidade JMS Criação de destinos temporários: é possível a criação programática de destinos, subordinados a uma conexão (Connection): TemporaryQueue mytempqueue= queuesession.createtemporaryqueue(); TemporaryTopic mytemptopic = topicsession.createtemporarytopic(); O destino temporário, e todas as mensagens contidas neste, são descartados quando a conexão é fechada.

Destino temporários Confiabilidade JMS Qualquer produtor pode enviar mensagens para um destino temporário, mas apenas consumidores criados sob a mesma conexão podem consumir mensagens deste. Uso comum - sistema requisição-resposta: Cabeçalho: JMSDestination = myqueue JMSReplyTo = tempqueue Cliente JMS tempqueue myqueue Cliente JMS

Confiabilidade JMS Assinaturas duráveis: após criada uma assinatura durável, um ou mais assinantes duráveis (um de cada vez) podem obter a assinatura e recuperar mensagens enviadas antes das suas criações individuais:

Confiabilidade JMS Transações locais (local transactions): uma sessão criada com suporte a transações disponibiliza dois métodos adicionais: mysession.commit( ) - efetiva a transação. mysession.rollback( ) - desfaz operações parciais da transação. Este suporte é simples, porém limitado Não pode ser usado em EJBs, que devem utilizar o mecanismo de transações distribuídas do JEE.

Confiabilidade JMS Em transações cuidado com a ordem das operações: Somente send()s ou receive()s = OK receive()s antes de send()s = OK send() de uma mensagem e após, tentativa de receive() da resposta na mesma transação = deadlock Causa: mensagens enviadas em uma sessão transacional não são de fato enviadas até o commit( )

Confiabilidade JMS Adicionalmente: uma mensagem enviada em uma transação não pode ser consumida na mesma transação. Isto ocorre porque este suporte à transação é local ao contexto de um cliente e um provedor JMS, que intervém entre o send e o receive:

JMS + Enterprise JavaBeans EJB: Qualquer tipo de enterprise bean pode atuar como um cliente JMS: Produzir mensagens. Consumir mensagens de forma síncrona - Consumer.receive( ); Para evitar uso desnecessário de recursos do servidor ( receive nunca satisfeito) utilizar receivenowait( ) ou receive( <timeout-ms> ): while ( ) { /* retorna null se não há mensagem em 10ms */ Message m = myconsumer.receivenowait( 10 );

JMS + Enterprise JavaBeans Por questão de performance recomenda-se realizar o lookup de objetos administrativos (fábricas de conexões e destinos) apenas no método ebjcreate( ) do bean, ao invés de realizar o lookup cada vez em que o objeto for necessário em um método de serviço do bean. É recomendado utilizar o suporte a transações distribuídas do container EJB (container-managed transactions) ou, em caso de requerimentos especiais da aplicação, outro mecanismo, como bean-managed transactions.

É importante JMS + Enterprise JavaBeans liberar os recursos JMS (sessões e conexões) quando não forem mais utilizadas. Se um recurso for utilizado apenas durante um método de negócio do bean, utilizar uma estrutura try-finally dentro do método: // criação de recursos JMS try { // operações que podem jogar exceções } /* opcionalmente: catch { } */ finally { // liberação dos recursos JMS }

JMS + Enterprise JavaBeans Se o recurso for utilizado durante todo o tempo de vida do EJB, é recomendável criar o recurso JMS (sessão ou conexão) no método ejbcreate( ), e destruir o recurso no método ejbremove( ).

Message-Driven Beans Message-Driven Beans - Um MDB é um bean que pode consumir mensagens de forma assíncrona, assim como um message listener: O método onmessage( ) do MDB é invocado quando uma mensagem chega no destino de interesse. O MDB pode registrar interesse em dois destinos: uma fila, ou em uma assinatura durável (tópico). Um MDB não possui interfaces home e remote, sendo constituído apenas de uma classe de bean.

Message-Driven Beans MDB x Session Beans Possui similaridades com Stateless Session Bean Instâncias com tempo de vida curto; Não guarda estado para um cliente específico; Podem ser criadas previamente em uma pool para atendimento de vários clientes; Podem manter alguns recursos em aberto entre requisições: conexões JMS, conexões com BD, referências EJB...

Message-Driven Beans MDB x message listener Um MDB possui algumas diferenças quanto a um message listener: setmessagelistener( ) não é invocado. A associação do MDB com um destino e uma fábrica de conexões é feita em tempo de deploy do bean para o container EJB.

Message-Driven Beans MDB Além de implementar os métodos ejbcreate( ), ejbremove( ) e onmessage( ), o MDB deve implementar o método: void setmessagedrivencontext( MessageDrivenContext ) Este método será invocado uma vez, antes de ejbcreate( ), para fornecer um objeto MessageDrivenContext. Atualmente, MessageDrivenContext = EJBContext.

Message-Driven Beans MDB O MessageDrivenContext fornece um método útil para utilização conjunta com container-managed transactions: void setrollbackonly( ) Este método marca a transação atual como falha, garantindo que ela não receberá commit. Ser invocado pelo MD quando uma exceção for lançada no seu método onmessage( ), garante o rollback da transação distribuída em que este recebimento de mensagem possa estar participando.

Exemplo - message-driven bean: import javax.ejb.*; import javax.naming.*; import javax.jms.*; public class MessageBean implements MessageDrivenBean, MessageListener { Message-Driven Beans private transient MessageDrivenContext mdc = null; private Context context; public MessageBean() { } /* construtor */ public void ejbcreate() { } public void ejbremove() { }

Message-Driven Beans Exemplo - message-driven bean: public void setmessagedrivencontext(messagedrivencontext mdc) { this.mdc = mdc; }

Message-Driven Beans Exemplo - message-driven bean: /* este MDB processa mensagens de texto */ public void onmessage(message inmessage) { TextMessage msg = null; try { if (inmessage instanceof TextMessage) { msg = (TextMessage) inmessage; System.out.println("MESSAGE BEAN: Message + "received: " + msg.gettext()); } else { System.out.println("Message of wrong type: " + inmessage.getclass().getname()); } }

Message-Driven Beans Exemplo - message-driven bean: } catch (JMSException e) { System.err.println("MessageBean.onMessage: " + "JMSException: " + e.tostring()); mdc.setrollbackonly(); /* se transação: falhou */ } catch (Throwable te) { System.err.println("MessageBean.onMessage: " + "Exception: + te.tostring()); }

JMS

Slides antigos

Modelo de Programação JMS Exemplo Obtendo uma Connection Factory: Context ctx = new InitialContext(); QueueConnectionFactory myqueuefact = (QueueConnectionFactory) ctx.lookup("queueconnectionfactory"); Obs.: Invocar InitialContext( ) sem parâmetros resulta na busca pelo arquivo jndi.properties determina o serviço JNDI (LDAP,...) e o espaço de nomes JNDI a ser utilizado para a construção do contexto.

Modelo de Programação JMS JEE Sun Criando destinos (filas e tópicos): j2eeadmin -addjmsdestination <nome JNDI da fila> queue j2eeadmin -addjmsdestination <nome JNDI do tópico> topic obs.: válido para versão 1.3 (revisar nas seguintes) Obtendo um destino no cliente, após criação: Queue myqueue = (Queue) ctx.lookup( Nome JNDI da fila );