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.
You may of course decide to use another JMS implementation. Currently the SwiftMQ product has been tested.
<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>
<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>
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(); }