Web components/JMS User's Guide

  1. JMS installation and configuration aspects
  2. Writing JMS operations within a web component
  3. JMS administration
  4. Running a WEB component performing JMS operations
It is possible for any web component (Servlet, JSP) to send or synchronously receive JMS messages. The web component programmer has the possibility to use resources (by the way of resource references) that may be JDBC (a DataSource) or JMS (a ConnectionFactory) connection factories. Thus, the web component programmer is able to provide JMS code inside of a web component method, in order to send a message toward a JMS Queue or Topic. The WEB Container is able to take into account these JMS operations within a global transaction which may include other resources such as databases.

Details about JMS should be found in the Java Message Service Specification 1.0.2.

In the JOnAS JMS integration, JOnAS makes use of a third party JMS implementation: currently the Joram opensource is integrated and delivered with JOnAS, the SwiftMQ product may also be used, other JMS provider implementations may easily be integrated. The JMS administered objects used by the WEB components, such as the connection factories and the destinations, may be created previously to the WEB component execution, by the way of the proprietary JMS implementation administration facilities. However, JOnAS provides "wrappers" upon such JMS administration APIs, allowing simple administration operations to be achieved automatically by the application server itself. This avoids the deployer to cope with proprietary administration APIs or tools. See JMS Administration.

JMS installation and configuration aspects

To use JMS with the JOnAS you do not need to perform any installation or configuration operation, JOnAS contains:

You may of course decide to use another JMS implementation. Currently the SwiftMQ product has been tested.

Writing JMS operations within a web component

In order to send (or synchronously receive) JMS messages, the web component programmer should have access to JMS administered objects, i.e. Connection Factories to create connections to JMS resources, and Destination objects (Queue or Topic) which are the JMS entities used as destination within JMS sending operations. Both are made available through JNDI by the JMS provider administration facility.

Accessing the Connection Factory

The Servlet specification introduces the concept of "Resource Manager Connection Factory References", which are objects used to create connections to a resource manager within a WEB component. Up to now, two kinds of Resource Manager Connection Factories are considered in the Servlet specification The second ones should be used by a web component to get JMS Connection Factories. The standard deployment descriptor should contain the following element:
      <resource-ref>
      <res-ref-name>jms/conFact</res-ref-name>
      <res-type>javax.jms.QueueConnectionFactory</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
      </resource-ref>
    
This means that the web component programmer will have access to a QueueConnectionFactory object using the JNDI name java:comp/env/jms/conFact. To obtain the factory object the web component should contain the code :
      QueueConnectionFactory qcf = (QueueConnectionFactory)
                 ctx.lookup("java:comp/env/jms/conFact");
    
The mapping to the actual JNDI name of the connection factory (as assigned by the JMS provider administration tool), QCF in the example, will be done in the JOnAS specific deployment descriptor with the following element:
      <jonas-resource>
      <res-ref-name>jms/conFact</res-ref-name>
      <jndi-name>QCF</jndi-name>
      </jonas-resource>
    

Accessing the Destination Object

Accessing a JMS destination within the code of a WEB component will require to use a resource environment reference, as defined in the Servlet specification. A resource environment reference is represented in the standard deployment descriptor as follows:
      <resource-env-ref>
      <resource-env-ref-name>jms/stockQueue</resource-env-ref-name>
      <resource-env-ref-type>javax.jms.Queue<resource-env-ref-type>
      </resource-env-ref>
    
And the web component code should contain
      Queue q = (Queue) ctx.lookup("java:comp/env/jms/stockQueue");
    
the mapping to the actual JNDI name (e.g. "myQueue") being done in the JOnAS specific deployment descriptor in the following way:
      <jonas-resource-env>
      <resource-env-ref-name>jms/stockQueue</resource-env-ref-name>
      <jndi-name>myQueue<jndi-name>
      </jonas-resource-env>
    

Writing JMS Operations

A typical WEB component method performing some JMS operations will look like the following (for sending a message):
    public void sendMyMessage() {
        QueueConnectionFactory qcf = (QueueConnectionFactory)
                ctx.lookup("java:comp/env/jms/conFact");
        Queue queue = (Queue) ctx.lookup("java:comp/env/jms/stockQueue");
        QueueConnection qc = qcf.createQueueConnection();
        QueueSession qs = qc.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        QueueSender sender = qs.createSender(queue);
        ObjectMessage msg = qs.createObjectMessage();
        msg.setObject("Hello");
        sender.send(msg);
        qs.close();
        qc.close();
    }
    
It is also possible for a WEB component to synchronously receive a message. A WEB component method performing synchronous message reception on a queue is illustrated below:
    public String recMsg() {
        QueueConnectionFactory qcf = (QueueConnectionFactory)
                ctx.lookup("java:comp/env/jms/conFact");
        Queue queue = (Queue) ctx.lookup("java:comp/env/jms/stockQueue");
        QueueConnection qc = qcf.createQueueConnection();
        QueueSession qs = qc.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
        QueueReceiver qr = qs.createReceiver(queue);
        qc.start();
        ObjectMessage msg = (ObjectMessage) qr.receive();
        String msgtxt =  (String) msg.getObject();
        qs.close();
        qc.close();
        return msgtxt;
    }
    
A method that performs JMS operations should always contain the session create and close statements, as follows:
    public void doSomethingWithJMS (...) {
        ...
        session = connection.create<Queue|Topic>Session(...);
        ... // JMS operations
        session.close();
    }
    
Of course, the contained JMS operations will be part of the transaction, if there is one, when the application server executes the method.

Be careful to never send and receive a given message in the same transaction, since the JMS sending operations are actually performed at commit time only !

The examples above illustrate point to point messaging, you may of course develop WEB components using the publish/subscribe JMS API, i.e. use the Topic instead of the Queue destination type. This allows you to broadcast a message to several message consumers at a time. The example below illustrates a typical WEB component method for publishing a message on a JMS topic.

    public void sendMsg(java.lang.String s) {
        TopicConnectionFactory tcf = (TopicConnectionFactory)
                       ictx.lookup("java:comp/env/jms/conFactSender");
        Topic topic = (Topic) ictx.lookup("java:comp/env/jms/topiclistener");
        TopicConnection tc = tcf.createTopicConnection();
        TopicSession session = tc.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
        TopicPublisher tp =  session.createPublisher(topic);
        ObjectMessage message = session.createObjectMessage();
        message.setObject(s);
        tp.publish(message);
        session.close();
        tc.close();
    }
    

JMS administration

JMS applications need some JMS administered objects: connection factories and destinations. These JMS administered objects are described in section Using JMS in EJBs part JMS administration.

Running a WEB component performing JMS operations

In order to have a WEB component performing some JMS operations, the steps to follow are described in the section Using JMS in EJBs part Running an EJB performing JMS operations.