as novidades do jms 2.0
DESCRIPTION
Conheça as novidades da nova especificação do Java Message ServiceTRANSCRIPT
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 1
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 2
As novidades do Java Message Service 2.0
Bruno Borges
Java EE Evangelist, Product Manager
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 3
The following is intended to outline our general product direction. It is intended
for information purposes only, and may not be incorporated into any contract.
It is not a commitment to deliver any material, code, or functionality, and should
not be relied upon in making purchasing decisions. The development, release,
and timing of any features or functionality described for Oracle’s products
remains at the sole discretion of Oracle.
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 4
JMS
API java para enviar e receber mensagens
Diversas implementações no mercado
Duas variações distintas
– Aplicações Java SE
– Aplicações Java EE (web, EJB, client)
suporta JTA e MDBs
remove funcionalidades consideradas inapropriadas em um ambiente
de servidor de aplicação gerenciado
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 5
O que o JMS é e não é
Uma API padronizada
– Não é um sistema de mensagens pronto para ser utilizado
– Não é um protocolo de comunicação
Define somente uma API Java
– Não define uma API para clientes de outras linguagens (C++, HTTP, C#,
etc)
Uma API para aplicações
– Não é (ainda) uma API para administrar, gerenciar ou monitorar
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 6
JMS 2.0
JMS 1.1: última atualização em 2002
JMS 2.0 proposto em 2011 pela JSR 343
– EG possui 20 membros:
FuseSource, IBM, Oracle, Pramati, Red Hat, TIBCO
– Public Review aprovado em 18 de Fevereiro de 2013
20 a favor, 4 abstenções
– Participação do SouJava
– Será lançado como parte do Java EE 7
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 7 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
ObjetivosJMS 2.0
Simplicidade e facilidade de uso
Novas funcionalidades de mensageria
Melhor integração com o Java EE
– API c/ maior clareza de acordo com a
especificação
– Configuração simplificada de recursos
– Padronização de configuração de MDBs
– Melhor plugabilidade entre servidores de aplicação
Pequenas correções
Cloud / PaaS postergadas p/ Java EE 8
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 8
JMS 2.0: Simplificação da API
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 9
Qual o problema da versão 1.1 da API?
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 10
JMS 1.1: Enviando uma mensagem
@Resource(lookup = "java:global/jms/demoConnectionFactory")
ConnectionFactory connectionFactory;
@Resource(lookup = "java:global/jms/demoQueue")
Queue demoQueue;
public void sendMessage(String payload) {
try {
Connection connection = connectionFactory.createConnection();
try {
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = session.createProducer(demoQueue);
TextMessage textMessage = session.createTextMessage(payload);
messageProducer.send(textMessage);
} finally {
connection.close();
}
} catch (JMSException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
13 linhas
de código
pra enviar
1 msg
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 16
Simplificação da JMS 1.1 API
Simplificar a API 1.1 existente sem quebrar compatibilidade
Definir a nova API de forma mais simplificada exigindo poucos objetos
– JMSContext, JMSProducer, JMSConsumer
No Java EE, permitir que o JMSContext seja injetado e gerenciado
pelo container
Estratégia
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 17
Simplificação da JMS 1.1 API
Precisa manter compatibilidade e limitar escopo de mudanças
Novos métodos javax.jms.Connection para criar Session:
– Método atual (será mantido)
– Novo método (para usar em ambiente Java SE)
– Novo método (para usar em ambiente Java EE)
API mais simples para criar uma Session
connection.createSession(transacted,deliveryMode)
connection.createSession(sessionMode)
connection.createSession()
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 18
Simplificação da JMS 1.1 API
Java EE
– com JTA: argumentos são ignorados. Sessão participa da tx
– sem JTA: ‘transacted’ é ignorado, sempre local-tx.
‘sessionMode’ é propcessado (AUTO_ACK ou DUPS_OK)
Java SE
– ‘transacted’ = true: sessão usa local-tx. ‘sessionMode’ é ignorado
– ‘transacted’ = false: sessão non-tx. ‘sessionMode’ será lido e interpretado
de acordo com a documentação
API mais simples para criar uma Session
connection.createSession(transacted,sessionMode)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 19
Simplificação da JMS 1.1 API
Java EE
– com JTA: ‘sessionMode’ é ignorado
– sem JTA: sessão non-tx. ‘sessionMode’ = AUTO ou DUPS_OK
Java SE
– ‘sessionMode’ = SESSION_TRANSACTED: possui local-tx
– ‘sessionMode’ = CLIENT, AUTO, DUPS_OK: non-tx, mensagens será ACK
pelo modo definido.
API mais simples para criar uma Session
connection.createSession(sessionMode)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 20
Simplificação da JMS 1.1 API
Java EE
– com JTA: participate da TX
– sem JTA: sessão non-tx. AUTO_ACK é usado
Java SE
– Sessão non-tx. AUTO_ACK é usado
API simplificada para criar uma Session
connection.createSession()
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 21
Simplificação da JMS 1.1 API
Definir objetos JMS como java.jang.AutoCloseable
– Connection
– Session
– MessageProducer
– MessageConsumer
– QueueBrowser
Requer Java SE 7
API simplificada para fechar os objetos JMS
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 22
Simplificação da JMS 1.1 API
Make JMS objects implement java.jang.AutoCloseable
– Connection, Session, MessageProducer, MessageConsumer,
QueueBrowser
API simplificada para fechar os objetos JMS
@Resource(lookup = "jms/connFactory")
ConnectionFactory cf;
@Resource(lookup="jms/inboundQueue")
Destination dest;
public void sendMessage (String payload) throws JMSException {
try ( Connection conn = connectionFactory.createConnection();
Session session = conn.createSession();
MessageProducer producer = session.createProducer(dest);
){
Message mess = sess.createTextMessage(payload);
producer.send(mess);
} catch(JMSException e){
// exception handling
}
}
close() é chamado
automaticamente
no final do bloco
Fecha recursos
dentro do bloco
try-with-resources
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 23
Nova API simplificada para o JMS 2.0
Introdução ao JMSContext e JMSProducer
@Resource(lookup = "java:global/jms/demoConnectionFactory")
ConnectionFactory connectionFactory;
@Resource(lookup = "java:global/jms/demoQueue")
Queue demoQueue;
public void sendMessageNew(String payload) {
try (JMSContext context = connectionFactory.createContext();){
context.createProducer().send(demoQueue, payload);
} catch (JMSRuntimeException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
13 linhas
reduzido
para 5
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 25
JMSContext (1/2)
Novo objeto que encapsula Connection, Session e MessageProducer
Criado através de um ConnectionFactory
Chamar close() depois de usar, ou colocar em um bloco try-with-
resources
Pode ser injetado (numa aplicação EJB ou Java EE Web)
JMSContext context = connectionFactory.createContext(sessionMode);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 26
JMSContext (2/2)
Pode ser criado a partir de outro JMSContext
(para reutilizar conexão – Java SE somente)
Usado para criar objetos JMSProducer
Usado para criar JMSConsumer
Métodos do JMSContext, JMSProducer e JMSConsumer só disparam
unchecked exceptions
JMSContext context2 = context1.createContext(sessionMode);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 27
JMSProducer
JMS 1.1
JMS 2.0
MessageProducer producer = session.createProducer();
producer.send(destination,message);
JMSProducer producer = context.createProducer();
producer.send(destination,message);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 28
JMSProducer
JMS 1.1
JMS 2.0
Configuração de delivery com Fluent API ou method chaining
context.createProducer().setDeliveryMode(DeliveryMode.NON_PERSISTENT).
setPriority(1).setTimeToLive(1000).send(destination,message);
MessageProducer producer = session.createProducer();
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
producer.setPriority(1);
producer.setTimeToLive(1000);
producer.send(destination,message);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 29
JMSProducer
JMS 1.1
JMS 2.0
Configuração de headers e propriedades de mensagens
context.createProducer().setProperty("foo","bar").send(destination,"Hello");
MessageProducer producer = session.createProducer();
TextMessage textMessage = session.createTextMessage("Hello);
textMessage.setStringProperty("foo","bar");
producer.send(destination,message);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 30
JMSProducer
Métodos do JMSProducer para enviar a Message
– send(Destination dest, Message message)
Não precisa criar um Message
– send(Destination dest, Map<String,Object> payload)
– send(Destination dest, Serializable payload)
– send(Destination dest, String payload)
– send(Destination dest, byte[] payload)
Envio de mensagens diretas
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 31
JMSConsumer
Mensagens são consumidas criando um objeto JMSConsumer
– Encapsula um MessageConsumer
– Funcionalidade e API similar do MessageConsumer
Synchronous
Asynchronous
Connection is automatically started (configurable)
JMSConsumer consumer = context.createConsumer(destination);
Message message = consumer.receive(1000);
JMSConsumer consumer = context.createConsumer(destination);
consumer.setMessageListener(messageListener);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 32
JMSConsumer
Métodos do JMSConsumer que retornam a Message
– Message receive();
– Message receive(long timeout);
– Message receiveNoWait();
Métodos do JMSConsumer que retornam o conteúdo da mensagem
diretamente
– <T> T receivePayload(Class<T> c);
– <T> T receivePayload(Class<T> c, long timeout);
– <T> T receivePayloadNoWait(Class<T> c);
Recebendo conteúdo de mensagens diretamente
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 33
JMSConsumer
Recebendo conteúdo de mensagens diretamente
public String receiveMessage() throws NamingException {
InitialContext initialContext = getInitialContext();
ConnectionFactory connectionFactory =
(ConnectionFactory) initialContext.lookup("jms/connectionFactory");
Queue inboundQueue = (Queue)initialContext.lookup("jms/inboundQueue");
try (JMSContext context = connectionFactory.createContext();) {
JMSConsumer consumer = context.createConsumer(inboundQueue);
return consumer.receivePayload(String.class);
}
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 34
Injeção de objetos JMSContext
Em um container EJB ou Java EE Web
@Inject
@JMSConnectionFactory("jms/connectionFactory")
private JMSContext context;
@Resource(mappedName = "jms/inboundQueue")
private Queue inboundQueue;
public void sendMessage (String payload) {
context.createProducer().send(inboundQueue, payload);
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 35
Injeção de objetos JMSContext
Em um container EJB ou Java EE Web
@Inject
@JMSConnectionFactory("jms/connectionFactory")
private JMSContext context;
@Resource(mappedName = "jms/inboundQueue")
private Queue inboundQueue;
public void sendMessage (String payload) {
context.createProducer().send(inboundQueue, payload);
}
Use @Inject
para injetar o
JMSContext,
especificando
connection
factory
Container se
responsabiliza em
fechar o objeto
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 36
Injeção de objetos JMSContext
Connection factory padrão do container
Com definição de Session Mode
Com definição de user e password
Em um container EJB ou Java EE Web
@Inject private JMSContext context;
@Inject
@JMSConnectionFactory("jms/connectionFactory")
@JMSSessionMode(JMSContext.AUTO_ACKNOWLEDGE)
private JMSContext context;
@Inject
@JMSConnectionFactory("jms/connectionFactory")
@JMSPasswordCredential(userName="admin",password="mypassword")
private JMSContext context;
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 37
Injeção de objetos JMSContext
Objetos JMSContext injetados possuem escopo
– Com JTA transaction, escopo é a transação
– Sem JTA transaction, escopo é o request
JMSContext é automaticamente fechado quando o escopo termina
Injete dois objetos JMSContext com mesmo escopo e terá o mesmo
objeto
– se valores de @JMSConnectionFactory, @JMSPasswordCredential e
@JMSSessionMode são idênticos
– Torna mais fácil usar a mesma sessão dentro de uma transação
Em um container EJB ou Java EE Web
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 38
JMS 2.0: Novas features da API
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 39
Mais fácil criar Durable Subscribers
Durable subscriptions são identificados por
{clientId, subscriptionName}
ClientId não é mais obrigatório quando usar durable subscriptions
Para MDBs, o container vai gerar um nome padrão (EJB 3.2)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 40
Delivery delay
Permite um cliente JMS agendar entrega futura de mensagem
Novo método no MessageProducer
Novo método no JMSProducer
Configure tempo minimo em ms para quem uma mensagem deve ser
retida no sistema até ser enviada
public JMSProducer setDeliveryDelay(long deliveryDelay)
public void setDeliveryDelay(long deliveryDelay)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 41
Envio Assíncrono
Envia uma mensagem e retorna imediatamente sem bloquear até o
ACK de que foi recebida pelo servidor
Uso de callback quando tiver o ACK do servidor
Novo método do MessageProducer
Disponível também no JMSProducer
messageProducer.send(message,completionListener)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 42
Envio Assíncrono
Aplicação define um CompletionListener
public interface CompletionListener {
void onCompletion(Message message);
void onException(Message message, Exception exception);
}
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 43
Melhor tratamento de mensagens ruins
JMS 1.1 define uma propriedade de mensagem opcional JMSXDeliveryCount.
– Quando usado, é setado pelo provedor JMS quando a mensagem é
recebida, e indica o número de vezes que esta mensagem foi entrege
(incluindo a primeira vez).
JMS 2.0 torna esta propriedade obrigatória pelas implementações
Torna a propriedade JMSMXDeliveryCount obrigatória
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 44
Múltiplos consumidores numa subscrição de tópico Permite consumo escalável de mensagems a partir de um Topic
Subscription
– Múltiplas threads, multiplas JVMs
Novos métodos para non-durable subscriptions
Métodos existentes para durable subscriptions
Disponível também no JMSContext
MessageConsumer messageConsumer=
session.createSharedConsumer(topic,sharedSubscriptionName);
MessageConsumer messageConsumer=
session.createDurableConsumer(topic,durableSubscriptionName);
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 45
Definição de recursos JMS simplificada no Java EE Em conjunto com JSR 342 (Java EE 7 platform)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 46
Definição de recursos JMS simplificada no Java EE
Java EE e JMS recomenda que aplicações devem obter o
ConnectionFactory e a Destination via JNDI
Mantém o código portável
Criar estes recursos é um incômodo para os desenvolvedores
O problema
@Resource(lookupName = "jms/inboundQueue")
private Queue inboundQueue;
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 47
Connection Factory default na plataforma
Se você quiser somente usar o serviço JMS do servidor de aplicação
Simplifica o uso de JMS na maioria dos casos
@Resource(lookup="java:comp/defaultJMSConnectionFactory")
ConnectionFactory myJMScf;
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 48
Definição de recursos JMS simplificada no Java EE
Aplicação pode especificar os JMS connection factories e JMS
destinations que precisa via anotações
Deployer pode então definir requerimentos com os deployment
descriptors
Servidor de aplicação pode usar esta informação para criar
automaticamente os recursos quando a aplicação for instalada
Equivalente às anotações referentes a @DataSourceDefinition
É opcional suportar estes recursos
Funções novas e opcionais no Java EE 7
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 49
Definição de recursos JMS simplificada no Java EE
Uso de anotações para definir recursos
@JMSDestinationDefinition(
name = "java:global/jms/demoQueue",
description = "Queue to use in demonstration",
className = "javax.jms.Queue",
destinationName="demoQueue")
@JMSConnectionFactoryDefinition(
name="java:global/jms/demoConnectionFactory",
className= "javax.jms.ConnectionFactory",
description="ConnectionFactory to use in demonstration")
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 50
Definição de recursos JMS simplificada no Java EE
Deployer configura informações específicas posteriormente
<jms-connection-factory>
<name>java:global/jms/demoConnectionFactory</name>
<property>
<name>addressList</name>
<value>mq://localhost:7676</value>
</property>
<max-pool-size>30</max-pool-size>
<min-pool-size>20</min-pool-size>
<max-idle-time>5</max-idle-time>
</jms-connection-factory>
<jms-destination>
<name>"java:global/jms/demoQueue</name>
<class-name>javax.jms.Queue</class-name>
<resource-adapter-name>jmsra</resource-adapter-name>
<destination-name>demoQueue</destination-name>
</jms-destination>
Pode definir
propriedades
específicas
do provedor
JMS
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 51
Configuração padronizada de MDBs Em conjunto com JSR 345 (EJB 3.2)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 52
Configuração padronizada de MDBs
Configuração de MDBs não é padronizada
EJB 3.1 não define como especificar
– Nome JNDI da queue or topic (usando annotation)
– Nome JNDI da connection factory
– clientID
– durableSubscriptionName
EJB 3.1 não define como que mensagens de tópicos devem ser
entregues para MDBs clusterizados
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 53
Configuração padronizada de MDBs
Também pode ser definido no ejb-jar.xml
Novas propriedades de ativação para Queue ou Topic
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName = "destinationLookup",
propertyValue = "jms/myTopic"),
. . .
})
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 54
Configuração padronizada de MDBs
Também pode ser definido no ejb-jar.xml
Novas propriedades de ativação para Queue ou Topic
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName = "connectionFactoryLookup",
propertyValue = "jms/myCF"),
. . .
})
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 55
Configuração padronizada de MDBs
Estas propriedades nunca tinham sido padronizadas
Novas propriedades de ativação para Queue ou Topic
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName = "subscriptionDurability",
propertyValue = "Durable"),
@ActivationConfigProperty(
propertyName = "clientId",
propertyValue = "myClientID"),
@ActivationConfigProperty(
propertyName = "subscriptionName",
propertyValue = "MySub"),
. . .
})
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 57
Topic delivery para MDBs em cluster Uma mensagem por instância ou uma por cluster?
Application server cluster
Application server instance
MDB MDB MDB
Application server instance
MDB MDB MDB
Application server instance
MDB MDB MDB
Topic
?
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 58
Topic delivery para MDBs em cluster
Se subscriptionName e clientId não estão definidos
– cada mensagem será entregue uma vez, por cluster
– instâncias do cluster compartilharão o mesmo nome de subscrição
Para desligar configure sharedSubscriptions para false
– cada mensagem será entregue uma por instância de MDB
– cada instância do servidor de aplicação terá uma subscription separada
Aplica-se a durable e non-durable subscriptions
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 59
Melhor plugabilidade com Java EE
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 60
Melhor plugabilidade com Java EE
Objetivo
– Facilitar o uso de um provedor JMS em outros servidores de aplicação
– e.g. aplicação GlassFish enviando mensagens para o WebLogic JMS
Solução
– Obrigar provedores JMS a oferecer um adaptador JCA
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 61
Melhor plugabilidade com Java EE
Java Connector Architecture é desenhado para:
– Integrar recursos transacionais com o servidor de aplicação
– processamento assíncrono de MDBs
Suporte ao JCA é obrigatório no Java EE
Muitos vendors de JMS vendors já oferecem adaptadores
JMS 2.0 obriga o provisionamento de adaptador JCA
Deve ser transparente para as aplicações!
usando a especificação Java Connector Architecture (JCA)
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 62 Copyright © 2012, Oracle and/or its affiliates. All rights reserved.
Novidades do JMS 2.0
Simplicidade e facilidade de uso
Novas features
– multi-threaded Topic Subscribers
– delivery delay
– envio async
Melhor integração com Java EE
– configuração de recursos simplificada
– Padronização na configuração de MDBs
– melhor plugabilidade entre servidores de aplicação
Muitas outras melhorias e correções
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 64
Experimente o Java EE 7
GlassFish 4.0
– http://glassfish.java.net/
– http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/
Open Message Queue 5.0
– http://mq.java.net/
– http://mq.java.net/5.0.html
JMS 2.0, EJB 3.2 and Java EE
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 65
Perguntas?
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 66
Graphic Section Divider
Copyright © 2012, Oracle and/or its affiliates. All rights reserved. 67