what's new in jms 2.0 - otn bangalore 2013

Post on 28-Jun-2015

153 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

What's new in JMS 2.0

TRANSCRIPT

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.1

Graphic Section Divider

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.2

Easier Messaging with JMS 2.0Jagadish RamuApplication Server GroupOracle

Copyright © 2013, 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 © 2013, Oracle and/or its affiliates. All rights reserved.4

Java Message Service (JMS)

l A Java API for sending and receiving messagesl Many competing implementationsl Two distinct API variants

l Java SE applicationsl Java EE applications – adds additional features

l JTA (XA) transactionsl Replaces async MessageListener with MDBs, l Injection of connection factories and destinations using

@Resource l (New!) Injection and management of JMSContext objects

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.5

What JMS is and isn't

A standard APINot a messaging system in itselfNot a wire protocol

Defines Java API onlyDoesn't define API for non-Java clients (e.g. C++, HTTP) - but many implementations do

An application APINot (currently) an admin, management or monitoring API

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.6

JMS 2.0

JMS 1.1 (2002)Dozens of implementations, both standalone and as part of a full Java EE provider

JMS 2.0 (2013)Launched in 2011 as JSR 343Released in 2013 with Java EE 7Available in Open Message Queue 5.0 (standalone JMS provider) and in GlassFish 4.0 (full Java EE provider)Other implementations announced or in progress

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.7

What's new in JMS 2.0

l Simpler and easier to usel New messaging featuresl Better Java EE integration

l Define differences between JMS in SE and EE more clearly

l Simpler resource configurationl Standardized configuration of JMS MDBs

l Minor corrections and clarifications

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.8

JMS 2.0Simpler and easier to use

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.9

JMS API simplifications

l Make minor simplifications to existing standard API where it won't break compatibility

l Define new simplified API requiring fewer objectsJMSContext, JMSProducer, JMSConsumerIn Java EE, allow JMSContext to be injected and managed by the container

Twin-track strategy

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.10

Why did JMS 1.1 need simplifying?

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.11

JMS 1.1: Sending a message@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 lines of code just to send a message

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.12

JMS 1.1: Sending a message@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); }}

must create several intermediate objects

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.13

JMS 1.1: Sending a message@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); }}

redundant and misleading arguments

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.14

JMS 1.1: Sending a message@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); }}

must close resourcesafter use!

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.15

JMS 1.1: Sending a message@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); }}

all methods throw checked exceptions

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.16

Minor simplifications to the existing standard API

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.17

Minor simplifications to the standard API

Methods on javax.jms.Connection to create a Session:l JMS 1.1 method remains

connection.createSession(transacted, acknowledgeMode)l New method combines two parameters into one:

connection.createSession(sessionMode)l New method mainly for Java EE

connection.createSession()

Simpler API to create a Session

Session.SESSION_TRANSACTED Session.AUTO_ACKNOWLEDGE, Session.CLIENT_ACKNOWLEDGE Session.DUPS_OK_ACKNOWLEDGE

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.18

Minor simplifications to the standard API

l Make JMS objects implement java.jang.AutoCloseableConnection Session MessageProducer MessageConsumer QueueBrowser

l Requires Java SE 7

Simpler API to close JMS objects

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.19

Minor simplifications to the standard JMS API

Make JMS objects implement java.jang.AutoCloseableConnection, Session, MessageProducer, MessageConsumer, QueueBrowser

Simpler API to close JMS objects

@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() is called automatically at end of block

Create closeable resources in a try-with-resources block

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.20

Completely new simplified API

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.21

Completely new simplified APIIntroducing JMSContext and 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 linesreduced to 5

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.22

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

Completely new simplified APIIntroducing JMSContext and JMSProducer

JMSContext combines Connection and Session

Payload can be sent directly

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.23

JMSContext (1/2)

l A new object which encapsulates a Connection, a Session and an anonymous MessageProducer

l Created from a ConnectionFactory

l Call close() after use, or create in a try-with-resources blockl Can also be injected (into a Java EE web or EJB application)

JMSContext context = connectionFactory.createContext(sessionMode);

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.24

JMSContext (2/2)

l Can also create from an existing JMSContext (to reuse its connection – Java SE only)

l Used to create JMSProducer objects for sending messagesl Used to create JMSConsumer objects for receiving messagesl Methods on JMSContext, JMSProducer and JMSConsumer throw only

unchecked exceptions

JMSContext context2 = context1.createContext(sessionMode);

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.25

JMSProducer

Messages are sent by creating a JMSProducer objectDoes not encapsulate a MessageProducer so is lightweightSupports method chaining for a fluid style

JMS 1.1

JMS 2.0

MessageProducer producer = session.createProducer();producer.send(destination,message);

JMSProducer producer = context.createProducer();producer.send(destination,message);

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.26

JMSProducer

JMS 1.1

JMS 2.0

Setting message delivery options using 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 © 2013, Oracle and/or its affiliates. All rights reserved.27

JMSProducer

JMS 1.1 (need to set on the message)

JMS 2.0 (can also set on the JMSProducer)

Setting message properties and headers

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 © 2013, Oracle and/or its affiliates. All rights reserved.28

JMSProducer

Methods on JMSProducer to send a Messagesend(Destination dest, Message message)

No need to create a Messagesend(Destination dest, Map<String,Object> payload)send(Destination dest, Serializable payload)send(Destination dest, String payload)send(Destination dest, byte[] payload)

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

Sending message bodies directly

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.29

JMSConsumer

Messages are consumed by creating a JMSConsumer objectEncapsulates a MessageConsumerSimilar functionality and API to 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 © 2013, Oracle and/or its affiliates. All rights reserved.30

JMSConsumerReceiving message bodies directly

Methods on JMSConsumer that return a MessageMessage receive();Message receive(long timeout);Message receiveNoWait();

Methods on JMSConsumer that return message body directly<T> T receiveBody(Class<T> c);<T> T receiveBody(Class<T> c, long timeout);<T> T receiveBodyNoWait(Class<T> c);

When consuming messages synchronously

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.31

JMSConsumerReceiving message bodies directly

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.receiveBody(String.class); } }

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.32

Extracting the body from a message

Old way

New way

In both the standard and simplified APIs

Message message = consumer.receive(1000);TextMessage textMessage = (TextMessage) message;String body = textMessage.getText();

Message message = consumer.receive(1000);String body = message.getBody(String.class);

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.33

Injection of JMSContext objectsinto a Java EE web or EJB container

@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 © 2013, Oracle and/or its affiliates. All rights reserved.34

Injection of JMSContext objects

Connection factory will default to platform default JMS

Specifying session mode

Specifying user and password (not for production use)

into a Java EE web or EJB container

@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 © 2013, Oracle and/or its affiliates. All rights reserved.35

Injection of JMSContext objects

l Injected JMSContext objects have a scopeIn a JTA transaction, scope is the transactionIf no JTA transaction, scope is the request

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

same objectIf @JMSConnectionFactory, @JMSPasswordCredential and

@JMSSessionMode annotations match Makes it easier to use same session within a transaction

into a Java EE web or EJB container

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.36

The four JMS APIs

Simplified API Standard API Legacy queue-specific API

Legacytopic-specific API

Introduced in

JMS 2.0 JMS 1.1 JMS 1.0 JMS 1.0

Main interfaces

ConnectionFactoryJMSContext JMSProducer JMSConsumer

ConnectionFactoryConnectionSessionMessageProducerMessageConsumer

QueueConnectionFactoryQueueConnectionQueueSession,QueueSender,QueueReceiver

TopicConnectionFactoryTopicConnectionTopicSessionTopicProducerTopicSubscriber

new and

simplified slightly

simplified deprecat

ed

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.37

New messaging features

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.38

Delivery delay

Allows a JMS client to schedule the future delivery of a messageNew method on MessageProducer

New method on JMSProducer

Sets minimum time in ms from that a message should be retained by the messaging system before delivery to a consumerWhy? If the business requires deferred processing, e.g. end of day

In both the standard and simplified APIs

public JMSProducer setDeliveryDelay(long deliveryDelay)

public void setDeliveryDelay(long deliveryDelay)

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.39

Async send

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

l Instead, when the acknowledgement is received, an asynchronous callback will be invoked

l New methods on MessageProducer

l Feature also available on JMSProducerl Why? Allows thread to do other work whilst waiting for the

acknowledgement

In both the standard and simplified APIs

messageProducer.send(message,completionListener)

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.40

Async send

Application specifies a CompletionListener instance

In both the standard and simplified APIs

public interface CompletionListener { void onCompletion(Message message); void onException(Message message, Exception exception);}

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.41

Better handling of "poison" messages

JMS 1.1 defines an optional JMS defined message property JMSXDeliveryCount.

When used, this is set by the JMS provider when a message is received, and is set to the number of times this message has been delivered (including the first time). JMS 2.0 will make this mandatory

Why? Allows app servers and applications to handle "poisonous" messages better

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.42

Multiple consumers on a topic subscription

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.43

How topics work in JMS 1.1

TopicProducer

Subscription

Consumer

Each message is copied to every subscription

In JMS 1.1, each subscription has a single consumer

Subscription may be persisted (durable) or memory-only (non-durable)

Subscription

Consumer

Subscription

Consumer

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.44

Shared subscriptions in JMS 2.0

TopicProducerConsumer

Shared Subscription

Each message is copied to every subscription A shared

subscription may have multiple consumers

Subscription may be persisted (durable) or memory-only (non-durable)

Unshared subscription

Consumer

Consumer

Consumer

Each message on the shared subscription is delivered to only one consumer

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.45

Easier definition of JMS resources in Java EE

(This is actually part of Java EE 7)

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.46

Easier definition of JMS resources in Java EE

l Java EE and JMS recommend applications should obtain JMS ConnectionFactory and Destination resources by lookup from JNDI

l Keeps application code portablel Creating these resources is a burden on the deployer, and is non-

standard

The problem

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

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.47

Platform default connection factory

If you simply want to use the application server's built-in JMS provider, with no special settings:

Making the simple case simple

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

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.48

Easier definition of JMS resources in Java EE

Application may specify the JMS connection factories and JMS destinations that it needs using annotations

New feature in Java EE 7

@JMSDestinationDefinition( name = "java:global/jms/myQueue", interfaceName = "javax.jms.Queue", destinationName = "demoQueue")

@JMSConnectionFactoryDefinition( name="java:global/jms/myCF")

JNDIname

JNDIname

queue/topic name

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.49

Easier definition of JMS resources in Java EE

Can specify additional standard or provider-specific properties

New feature in Java EE 7

@JMSDestinationDefinition( name = "java:global/jms/myQueue", interfaceName = "javax.jms.Queue", destinationName = "demoQueue")

@JMSConnectionFactoryDefinition( name="java:global/jms/myCF", maxPoolSize = 30, minPoolSize= 20, properties = { "addressList=mq://localhost:7676", "reconnectEnabled=true" })

standard properties

non-standard properties

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.50

Easier definition of JMS resources in Java EE

Multiple definitions of same type must be wrapped in collection annotations (due to restriction in how Java annotations work)

New feature in Java EE 7

@JMSDestinationDefinitions({ @JMSDestinationDefinition( name = "java:global/jms/myQueue1", interfaceName = "javax.jms.Queue", destinationName = "demoQueue1" ), @JMSDestinationDefinition( name = "java:global/jms/myQueue2", interfaceName = "javax.jms.Queue", destinationName = "demoQueue2" )})

@JMSConnectionFactoryDefinitions({ @JMSConnectionFactoryDefinition( name="java:global/jms/myCF1" ), @JMSConnectionFactoryDefinition( name="java:global/jms/myCF2" )})

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.51

Easier definition of JMS resources in Java EE

Alternatively application may specify the JMS connection factories and JMS destinations that it needs in the XML deployment descriptor

New feature in Java EE 7

<jms-destination> <name> java:global/jms/myQueue </name> <interface-name> javax.jms.Queue </interface-name> <destination-name> demoQueue </destination-name></jms-destination>

<jms-connection-factory> <name>java:global/jms/myCF</name> <max-pool-size>30</max-pool-size> <min-pool-size>20</min-pool-size> <property> <name>addressList</name> <value>mq://localhost:7676</value> </property> <property> <name>reconnectEnabled</name> <value>true</value> </property></jms-connection-factory>

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.52

Easier definition of JMS resources in Java EE

Resources configured in this way must be in one of the following namespaces:java:comp – may be used within same component onlyjava:module – may be used within same module onlyjava:app – may be used within same application onlyjava:global – may be used within any application

May be referenced just like any other resource (e.g. @Resource)

Available namespaces

@Resource(lookup="java:global/jms/myCF")ConnectionFactory myCF;

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.53

More standardized configuration of JMS MDBs

Joint effort with JSR 345 (EJB 3.2)

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.54

More standardized configuration of JMS MDBs

l Configuration of JMS MDBs is surprisingly non-standardl EJB 3.1 does not define how to specify

JNDI name of queue or topic (using annotation)JNDI name of connection factoryClientIDDurableSubscriptionName

l EJB 3.1 does not define how topic messages delivered to clustered MDBs

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.55

More standardized configuration of JMS MDBs

Can also be configured in ejb-jar.xml

New activation property to specify the queue or topic

@MessageDriven(activationConfig = { @ActivationConfigProperty( propertyName = "destinationLookup", propertyValue = "jms/myTopic"), . . .})

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.56

More standardized configuration of JMS MDBs

Can also be configured in ejb-jar.xml

New activation property to specify the connection factory

@MessageDriven(activationConfig = { @ActivationConfigProperty( propertyName = "connectionFactoryLookup", propertyValue = "jms/myCF"), . . .})

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.57

More standardized configuration of JMS MDBs

Surprisingly, these have never been standardized before

New activation properties to specify durable subscriptions

@MessageDriven(activationConfig = { @ActivationConfigProperty( propertyName = "subscriptionDurability", propertyValue = "Durable"), @ActivationConfigProperty( propertyName = "clientId", propertyValue = "myClientID"), @ActivationConfigProperty( propertyName = "subscriptionName", propertyValue = "MySub"), . . .})

clientId optional even for durable subscriptions

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.58

What’s new in JMS 2.0

l Simplicity and ease of usel New messaging featuresl Multi-threaded topic subscribers

Delivery delayAsync send

l Better Java EE integrationSimpler resource configurationStandardized configuration of JMS MDBs

l Minor corrections and clarifications

Summary

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.59

Try JMS 2.0

l JMS 2.0 in a standalone provider (for Java SE applications)Open Message Queue 5.0 mq.java.net/

l JMS 2.0 in a full Java EE 7 application serverGlassFish 4.0 glassfish.java.net/

l Try other implementations as they are releasedl See also jms-spec.java.net for lots of useful links

JMS 2.0, EJB 3.2 and Java EE 7

Copyright © 2013, Oracle and/or its affiliates. All rights reserved.60

top related