jms.next(): jms 2.0 and beyond

42
JMS.Next(): JMS 2.0 and Beyond Reza Rahman Java EE/GlassFish Evangelist [email protected] @reza_rahman

Upload: reza-rahman

Post on 15-Jan-2015

38.705 views

Category:

Technology


3 download

DESCRIPTION

JMS is the Java standard for accessing enterprise messaging systems. This session introduces JMS 2.0 (JSR 343), the first update in more than a decade and easily the longest-awaited component of the forthcoming Java EE 7 standard. The biggest new feature of JMS 2.0 is a new API that makes JMS much easier to use, especially in a Java EE application. JMS 2.0 also provides API features to support greater scalability as well as additional messaging features and a long list of minor enhancements and clarifications. With JMS 2.0 final with Java EE 7, now is an ideal time to find out more about it. In this session, we will also discuss what might be next for the JMS specification.

TRANSCRIPT

Page 1: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public1

JMS.Next(): JMS 2.0 and BeyondReza RahmanJava EE/GlassFish [email protected]@reza_rahman

Page 2: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public2

JMS

Small, successful Java API for Message Oriented Middleware (MOM) JMS 1.1 – 2002

– J2EE era!

JMS 2 – 2013– Included in Java EE 7

Overdue and well received JMS 2.1 starting soon

– Included in Java EE 8

– Projected delivery 2016

Page 3: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public3Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public

JMS 2 Goals

API Modernization

Some New Features

Java EE Alignment

EJB3/MDB Alignment

Minor Corrections and Clarifications

Page 4: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public4

Modernizing the API

Page 5: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public5

JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory")private ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue")private 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); }}

Page 6: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public6

Simplifying the API

Maintain backwards compatibility! Simplify existing JMS API where possible Define new abstractions where needed

– JMSContext, JMSProducer, JMSConsumer

Take advantage of modern Java EE paradigms– Annotations

– Convention-over-configuration

– Injection/scoping

Strategy

Page 7: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public7

Streamlining Session Creation

Methods in javax.jms.Connection to create a Session:– Existing method (will remain)

connection.createSession(transacted, deliveryMode)

– New method mainly for Java SE connection.createSession(sessionMode)

– New method mainly for Java EE connection.createSession()

Page 8: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public8

Auto Closing JMS Objects

Primarily useful in Java SE Make JMS objects implement java.jang.AutoCloseable

– Connection

– Session

– MessageProducer

– MessageConsumer

– QueueBrowser

Page 9: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public9

JMS Auto Closable Example

@Resource(lookup = "jms/connFactory")private ConnectionFactory cf;@Resource(lookup="jms/inboundQueue")Destination dest;

public void sendMessage (String payload) throws JMSException { try (Connection conn = cf.createConnection(); Session session = conn.createSession(); MessageProducer producer = session.createProducer(dest); ){ Message mess = sess.createTextMessage(payload); producer.send(mess); } catch(JMSException e){ // exception handling }}

Page 10: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public10

A First Look at the New API

@Resource(lookup = "java:global/jms/demoConnectionFactory")private ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue")private 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); }}

Page 11: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public11

JMSContext

An abstraction that encapsulates Connection, Session, Producer and Consumer

– Created from ConnectionFactory JMSContext context = connectionFactory.createContext(sessionMode);

– Used to create JMSProducer objects for sending messages

– Used to create JMSConsumer objects for receiving messages

Methods on JMSContext, JMSProducer and JMSConsumer throw only unchecked exceptions

Page 12: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public12

JMSProducer

Messages are sent by creating a JMSProducer object Geared towards common use cases while retaining flexibility Fluent API

Page 13: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public13

JMSProducer Example

JMS 1.1

JMS 2

Setting message delivery options

MessageProducer producer = session.createProducer();producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);producer.setPriority(1);producer.setTimeToLive(1000);producer.send(destination,message);

context.createProducer().setDeliveryMode(DeliveryMode.NON_PERSISTENT) .setPriority(1).setTimeToLive(1000).send(destination, message);

Page 14: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public14

JMSProducer Example

JMS 1.1

JMS 2

Setting message properties and headers

MessageProducer producer = session.createProducer();TextMessage textMessage = session.createTextMessage("Hello);textMessage.setStringProperty("foo", "bar");producer.send(destination, message);

context.createProducer().setProperty("foo","bar").send(destination,"Hello");

Page 15: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public15

Sending Message Payloads Directly

Sending just the payload– send(Destination dest, String payload)

– send(Destination dest, Serializable payload)

– send(Destination dest, byte[] payload)

– send(Destination dest, Map<String, Object> payload)

– Use methods on JMSProducer to set delivery options, message headers and message properties

Sending JMS Message Object– send(Destination dest, Message message)

Page 16: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public16

JMSConsumer

Messages are consumed by creating a JMSConsumer object Geared towards common use cases while retaining flexibility

– Underlying connection is automatically started (configurable)

Page 17: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public17

Receiving Message Payloads Directly

Methods on JMSConsumer that return message payload directly:– <T> T receivePayload(Class<T> c);

– <T> T receivePayload(Class<T> c, long timeout);

– <T> T receivePayloadNoWait(Class<T> c);

You can still return a JMS Message Object:– Message receive();

– Message receive(long timeout);

– Message receiveNoWait();

Page 18: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public18

JMSConsumer Example

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); } }

Page 19: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public19

Enter the Injection Dragon

@Inject@JMSConnectionFactory("jms/connectionFactory")private JMSContext context;

@Resource(mappedName = "jms/inboundQueue") private Queue inboundQueue;

public void sendMessage (String payload) { context.createProducer().send(inboundQueue, payload); }

Page 20: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public20

Injection of JMSContext Objects

Connection factory will default to platform default JMS

Specifying session mode

Specifying username and password (may be aliased)

@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;

Page 21: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public21

Injection Under the Hood

Injected JMSContext objects have a scope– In a JTA transaction, scope is the transaction

– If no JTA transaction, scope is the request

JMSContext is automatically closed when scope ends Inject two JMSContext objects within the same scope and you get the

same object– If @JMSConnectionFactory, @JMSPasswordCredential and

@JMSSessionMode annotations match

– Makes it easier to use same session within a transaction

Page 22: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public22

The New Features

Page 23: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public23

Delivery Delay

Allows future timed delivery of a message– Deferred processing, e.g. end of day

Method on JMSProducer

Sets minimum time in ms from that a message should be retained by the messaging system before delivery to a consumer

Also available in the old API

public void setDeliveryDelay(long deliveryDelay)

Page 24: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public24

Asynchronous Send

Send a message and return immediately without blocking until an acknowledgement has been received from the JMS server

– Allows thread to do other work whilst waiting for acknowledgement

When the acknowledgement is received an asynchronous callback will be invoked

Method on JMSProducer:

Also available in the old API

producer.send(message, completionListener)

Page 25: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public25

Asynchronous Send Listener

public interface CompletionListener {

void onCompletion(Message message);

void onException(Message message, Exception exception);

}

Page 26: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public26

Better Handling of Poison Messages

JMS 1.1 defines optional JMS message property JMSXDeliveryCount– Number of times message has been delivered

JMS 2 makes this mandatory Allows applications (and the JMS provider) to handle poison messages

better– Not a replacement to dead letter queues, etc

JMSXDeliveryCount mandatory

Page 27: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public27

Multiple Consumers on a Topic Subscription

Allows scalable consumption of messages from a topic subscription– multiple threads, multiple JVMs

New methods needed for non-durable subscriptions:

Existing methods used for durable subscriptions:

Also available in old API

JMSConsumer consumer = context.createSharedConsumer(topic, sharedSubscriptionName);

JMSConsumer consumer = context.createDurableConsumer(topic, durableSubscriptionName);

Page 28: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public28

Java EE Alignment

Page 29: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public29

Platform Default Connection Factory

Ships preconfigured with the runtime Useful for majority of cases

@Resource(lookup="java:comp/defaultJMSConnectionFactory")ConnectionFactory myJMScf;

Page 30: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public30

Defining JMS Resources

@JMSConnectionFactoryDefinition( name = "java:global/jms/demoConnectionFactory", interfaceName = "javax.jms.ConnectionFactory", description = "ConnectionFactory to use in demonstration")

@JMSDestinationDefinition( name = "java:global/jms/demoQueue", description = "Queue to use in demonstration", interfaceName = "javax.jms.Queue", destinationName = "demoQueue")

Page 31: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public31

Supplanted/Overridden in XML…

<jms-destination> <name>java:global/jms/demoQueue</name> <interface-name>javax.jms.Queue</interface-name> <resource-adapter-name>jmsra</resource-adapter-name> <destination-name>demoQueue</destination-name></jms-destination>

<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>

Page 32: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public32

EJB3/MDB Alignment

Page 33: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public33

Better Standard Configuration for MDBs

Configuration of MDBs surprisingly non-standard– JNDI name of queue or topic

– JNDI name of connection factory

– Client ID

– Durable subscription name

Page 34: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public34

Specifying Queue or Topic

@MessageDriven(activationConfig = {

@ActivationConfigProperty(

propertyName = "destinationLookup",

propertyValue = "jms/myTopic"),

...

})

Page 35: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public35

Specifying Connection Factory

@MessageDriven(activationConfig = {

@ActivationConfigProperty(

propertyName = "connectionFactoryLookup",

propertyValue = "jms/myCF"),

...

})

Page 36: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public36

Specifying Durable Subscriptions

@MessageDriven(activationConfig = {

@ActivationConfigProperty(

propertyName = "subscriptionDurability",

propertyValue = "Durable"),

@ActivationConfigProperty(

propertyName = "clientId",

propertyValue = "myClientID"),

@ActivationConfigProperty(

propertyName = "subscriptionName",

propertyValue = "MySub"),

...

})

Page 37: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public37

Try it Out!

http://dlc.sun.com.edgesuite.net/glassfish/4.0.1/promoted/

Page 38: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public38

JMS 2 Implementations

GlassFish

Java EE 7

Java EE 6

TomEE

Page 39: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public39

JMS 2.1

Declarative JMS Listeners– https://java.net/jira/browse/JMS_SPEC-134

Cloud/Multitenancy– https://java.net/jira/browse/JMS_SPEC-57

Java SE 8 Alignment– https://java.net/jira/browse/JMS_SPEC-134

JMS/Java EE Pluggability– https://java.net/jira/browse/JMS_SPEC-25

Java SE Bootstrap– https://java.net/jira/browse/JMS_SPEC-89

Management/Monitoring– https://java.net/jira/browse/JMS_SPEC-18

Minor fixes and clarifications

Page 40: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public40

Summary

Long awaited and well received API modernization Some new features Java EE alignment EJB3/MDB alignment Minor corrections and clarifications Get involved in JMS 2.1!

Page 41: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public41

Learning More

Java EE/JMS Tutorials– http://docs.oracle.com/javaee/7/tutorial/doc/partmessaging.htm

JMS 2 Hands-on-Lab– https://github.com/m-reza-rahman/jms2-lab

JMS Transparent Expert Group– http://jms-spec.java.net

Java EE 7 Reference Implementation– http://glassfish.org

JMS Reference Implementation– http://mq.java.net

The Aquarium– http://blogs.oracle.com/theaquarium

Page 42: JMS.Next(): JMS 2.0 and Beyond

Copyright © 2012, Oracle and/or its affiliates. All rights reserved. Public42