Changes to improve ease-of-development

Clarification of relationship between JMS and other Java EE

specifications

specifications Definition of a new mandatory API to allow any JMS provider to

be integrated with any other Java EE Application Server

be integrated with any other Java EE Application Server Other enhancements as requested by the community





@Stateless

public class MessageSender {



@Inject

JMSContext context;



@Resource(mappedName="java:global/jms/myQueue")

Queue queue;



public void sendMessage(String message) {

context.createProducer().send(queue, message);

}

}



JMSContext is a new interface introduced in the

simplified API in JMS 2.0. This combines in a single object the

functionality of two separate objects from the JMS 1.1 API: a Connection

and a Session .







A JMSContext may be injected in the Java EE web

and EJB containers using the @Inject annotation. A

JMSContext created in this way is described as

being container-managed . A container-managed JMSContext

will be closed automatically by the container. Applications

running in the Java EE web and EJB containers are not permitted

to create more than one active session on a connection. This

allows to combine them in a single object offering a simpler

API. This is the recommended way for creating JMS context in

Java EE applications.







A JMSContext may be created by calling one of the

createContext methods on a ConnectionFactory .

A JMSContext that is created this way is described

as being application-managed . An application-managed JMSContext

must be closed when no longer needed by calling its close

method. Applications running in a Java SE environment or in the

Java EE application client container are permitted to create

multiple active sessions on the same connection. This allows the

same physical connection to be used in multiple threads

simultaneously. The createContext method is

recommended to create JMSContext in such

applications.





is a new interface introduced in the simplified API in JMS 2.0. This combines in a single object the functionality of two separate objects from the JMS 1.1 API: a and a . A may be injected in the Java EE web and EJB containers using the annotation. A created in this way is described as being . A container-managed will be closed automatically by the container. Applications running in the Java EE web and EJB containers are not permitted to create more than one active session on a connection. This allows to combine them in a single object offering a simpler API. This is the recommended way for creating JMS context in Java EE applications. A may be created by calling one of the methods on a . A that is created this way is described as being . An application-managed must be closed when no longer needed by calling its method. Applications running in a Java SE environment or in the Java EE application client container are permitted to create multiple active sessions on the same connection. This allows the same physical connection to be used in multiple threads simultaneously. The method is recommended to create in such applications. The Java EE Platform requires a preconfigured JMS ConnectionFactory

accessible to the application under the JNDI name:

java:comp/DefaultJMSConnectionFactory

The annotation @JMSConnectionFactory may be used

to specify the JNDI lookup name of the ConnectionFactory

used to create the JMSContext as:

@Inject

@JMSConnectionFactory("java:comp/DefaultJMSConnectionFactory")

JMSContext context;



If no lookup name is specified or the @JMSConnectionFactory

is omitted then the platform default JMS connection factory will

be used. The above code fragment is equivalent to:

@Inject

JMSContext context;



accessible to the application under the JNDI name: The annotation may be used to specify the JNDI lookup name of the used to create the JMSContext as: If no lookup name is specified or the is omitted then the platform default JMS connection factory will be used. The above code fragment is equivalent to: @Resource defines a dependency on a resource

needed by the application. In this case, it specifies the JNDI

name of the destination to which the message needs to be sent.





defines a dependency on a resource needed by the application. In this case, it specifies the JNDI name of the destination to which the message needs to be sent. When an application needs to send messages it uses the createProducer

method to create JMSProducer which provides

methods to configure and send messages. The various setProperty

methods are used to set property on the message being sent.

There are several other methods like setPriority ,

setDeliveryDelay , and setTimeToLive

to set other quality-of-service attributes for the message being

sent.







Messages may be sent synchronously or asynchronously.

Synchronous messages are sent using one of the send

methods. Asynchronous messages are sent using setAsync

method and assigning a CompletionListener . When

the message has been successfully sent the JMS provider invokes

the callback method onCompletion on the CompletionListener

object. If the message is not sent for some reason or an

acknowledgement from the remote JMS server is not received then

onException callback method is called. An

asynchronous send is not permitted in a Java EE application.





@Stateless

public class MessageReceiverSync {



@Inject

private JMSContext context;



@Resource(mappedName="java:global/jms/myQueue")

Queue myQueue;



public String receiveMessage() {

String message = context.createConsumer(myQueue).receiveBody(String.class, 1000);

return "Received " + message;

}

}



JMSContext referring to the preconfigured JMS ConnectionFactory

is injected by the container.

referring to the preconfigured JMS is injected by the container. @Resource defines a dependency on the JMS

destination on which the message is received.

defines a dependency on the JMS destination on which the message is received. When an application needs to receive messages it uses one of

the several createConsumer or createDurableConsumer

methods to create a JMSConsumer . createConsumer

creates a non-durable subscription on the specified destination.

This means that a client will only see the messages published on

the destination when the subscriber is active. If the subscriber

is not active, it is missing messages published on the

destination. createDurableConsumer creates an

unshared durable subscription of a specified topic and creates a

consumer on that subscription. This allows the subscriber will

receive all messages published on a topic, including the ones

published when there is no active consumer associated with it.

The JMS provider retains a record of this durable subscription

and ensures that all messages from the topic's publishers are

retained until they are delivered to, and acknowledged by, a

consumer on this durable subscription or until they have

expired.







A JMSConsumer provides methods to receive messages

either synchronously or asynchronously. receive

methods are used for synchronous delivery of the messages. A MessageListener

object may be registered with the client for asynchronous

delivery of the messages. onMessage method of the

MessageListener object are called as messages are

received. Asynchronous delivery of messages will not work until

MQ-264 is

fixed.





@JMSDestinationDefinition(name = "java:global/jms/myQueue",

resourceAdapterName = "jmsra",

className = "javax.jms.Queue",

destinationName="queue1234",

description="My Queue")

@WebServlet(urlPatterns = {"/TestServlet"})

public class TestServlet extends HttpServlet {



@EJB MessageSender sender;



@EJB MessageReceiverSync receiver;





void doGet(HttpServletRequest request, HttpServletResponse response) {

. . .

String m = "Hello there";

sender.sendMessage(m);

out.format("Message sent: %1$s.<br>", m);

out.println("Receiving message...<br>");

String message = receiver.receiveMessage();

out.println("Message received: " + message);

. . .

}



@JMSDestinationDefinition defines the JMS destination. The name

attribute defines the JNDI name of the destination being

defined, destinationName attribute defines the

name of the queue or topic, and className

attribute defines the JMS destination implementation class name.

attribute defines the JNDI name of the destination being defined, attribute defines the name of the queue or topic, and attribute defines the JMS destination implementation class name. doGet method uses the injected EJBs to send and

receive the message.





href="https://blogs.oracle.com/arungupta/entry/jms_2_0_early_draft">JMS2.0 Early Draft - Simplified API Sample Code explained some ofthe changes that are made in JMS 2.0 to "catch up" with all thechanges in the Java SE and EE platform over the past few years. Themain goals of JMS 2.0 are:Thisipheay (TOTD) willexplain a simple sample showing how to send a message and receive itsynchronously. The complete source code for the sample can be href="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/File/14fac9dfbcc0132808096e88d5f80a87/totd191_send_message_sample.zip">downloadedhere.This is a Stateless EJB that has a single method to send a message.In this code:This is a Stateless EJB that has a single method to receive themessage synchronously.In this code:Next is a Servlet that ties all the pieces together. It defines theJMS Destination and send and receive the message using thepreviously defined EJBs.In this code:The complete source code for the sample can be href="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/File/14fac9dfbcc0132808096e88d5f80a87/totd191_send_message_sample.zip">downloadedhere. "mvn package" and deploy the generated WAR file.Download href="http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/">GlassFish4 build 68 onwards and try this sample today!The latest progress on JMS 2.0 can be tracked at:

Help us make JMS 2.0 better, simpler, easier to use. Join href="http://java.net/projects/jms-spec/lists/users/archive">users@jms-spec

and contribute!





