<document>
  <header>
    <product>resin-ee</product>
    <title>JMS Listener</title>
        <description>
          <p>Introduces the JMS message listener configured with JCA.</p>
        </description>
    <type>tutorial</type>
    <tutorial-startpage>send</tutorial-startpage>
  </header>

<body>
<summary/>

<s1 title="Files in this tutorial">
<deftable>
<tr><td><viewfile-link file="WEB-INF/web.xml"/>
    </td><td>Configures the Queue, MessageSender, MessageListener.
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/MyListener.java"/>
    </td><td>The message listener.
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/MessageServlet.java"/>
    </td><td>The message servlet
</td></tr></deftable>
</s1>

<s1 title="Overview">

<p>Messaging lets a servlet delegate processing to a batch process either
on the same machine or on a separate machine.  The servlet creates a message
and sends it to a queue.  The servlet immediately completes and when the
batch process is ready, it processes the message.</p>

<p>Messaging is therefore comprised of three main components:
</p><ul>
<li>A <var>Producer</var> creates messages and sends them to
a <var>Queue</var>.  The Producer could be something like a Servlet.
</li><li>A <var>Queue</var> stores the messages from the Produces and provides
them to a Consumer when ready.  The Queue is implemented by the
messaging provider.
</li><li>A <var>Consumer</var> processes messages as they become
available in the Queue.  The <var>Consumer</var> is typically a bean
implementing the <code>MessageListener</code> interface.
</li></ul>

</s1>

<s1 title="Producer (MessageServlet)">

<p>In this example, the Producer is a Servlet which sends a simple message.
The Producer uses a <code>MessageSender</code> configured in the web.xml
to send the message.</p>

<example title="MessageServlet">
String message = "sample message";

MessageSender sender = ...; // JNDI lookup

sender.send(null, message);
</example>

<p>In this configuration, the <code>MessageSender</code> is a
<code>com.caucho.services.message.MessageSender</code>.  It's also possible
to use the full JMS <code>MessageProducer</code> which is more verbose.
The <code>MessageSender</code> is an interface available in the open
source <a href="http://www.caucho.com/hessian">Hessian distribution</a>,
so it can be used in other application servers as a convenient facade.</p>

<p>The <code>send</code> method completes as soon as
the message is stored in the queue.  Laster, when a thread is available, the
Queue will send the message to the Consumer.</p>

</s1>

<s1 title="Consumer (MyListener)">

<p>The Queue delivers message to the Consumer one by one.  When the
Consumer finishes processing a message the Queue will deliver the next
available message.</p>

<p>The Consumer implements <code>javax.jms.MessageListener</code>, and
will therefore be identical code in any application server.  The
Consumer might even be on a different server or use a different
application server.</p>

<p>In this example, the Consumer just logs the message.</p>

<example title="MyListener">
package example;

import java.util.logging.Logger;
import java.util.logging.Level;

import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.MessageListener;

public class MyListener implements MessageListener {
  private static final Logger log =
    Logger.getLogger(MyListener.class.getName());

  public void onMessage(Message message)
  {
    try {
      TextMessage textMessage = (TextMessage) message;

      log.info("received: " + textMessage.getText());

      _lastMessage = textMessage.getText();
    } catch (Throwable e) {
      log.log(Level.WARNING, e.toString(), e);
    }
  }
}
</example>

</s1>

<s1 title="Configuration">

<p>The configuration is responsible for three things:</p>
<ul>
<li>Configuring the Queue
</li><li>Configuring the MessageSender
</li><li>Configuring the MessageListener
</li></ul>

<p>The JMS <code>Queue</code> and its <code>ConnectionFactory</code>
are configured in the &lt;resource-adapter&gt; section.  Any JMS 1.1
implementation may be used for the &lt;connection-factory&gt; and
&lt;destination&gt;.</p>

<p>The &lt;connection-factory&gt; configures the MessageSender and saves
it in JNDI.</p>

<p>The &lt;message-listener&gt; and &lt;endpoint-factory&gt; configures
the MessageListener.</p>

<example title="web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;
  &lt;connector&gt;
    &lt;type&gt;com.caucho.jms.jca.ResourceAdapterImpl&lt;/type&gt;

    &lt;resource-adapter&gt;
      &lt;init&gt;
        &lt;connection-factory resin:type="com.caucho.jms.ConnectionFactoryImpl"/&gt;

        &lt;destination resin:type="com.caucho.jms.memory.MemoryQueue"/&gt;
      &lt;/init&gt;
    &lt;/resource-adapter&gt;

    &lt;connection-factory jndi-name="jms/sender"
                        type="com.caucho.jms.jca.MessageSenderManager"/&gt;

    &lt;message-listener type="com.caucho.jms.jca.MessageListenerSpec"&gt;
      &lt;endpoint-factory type="com.caucho.jms.jca.ListenerEndpointFactory"&gt;
        &lt;init&gt;
          &lt;listener resin:type="example.MyListener"/&gt;
        &lt;/init&gt;
      &lt;/endpoint-factory&gt;
    &lt;/message-listener&gt;
  &lt;/connector&gt;
&lt;/web-app&gt;
</example>

<deftable>
<tr><th>tag</th><th>meaning
</th></tr><tr><td>connector</td><td>top-level configuration for the JCA connector
</td></tr><tr><td>type</td><td>The type of the connector.
</td></tr><tr><td>resource-adapter</td><td>configures the connector/queue as a whole
</td></tr><tr><td>init</td><td>Bean-style initialization for each resource
</td></tr><tr><td>connection-factory</td><td>The JMS ConnectionFactory class
</td></tr><tr><td>resin:type</td><td>The class name
</td></tr><tr><td>destination</td><td>The JMS Queue or Topic
</td></tr><tr><td>connection-factory</td><td>Configures a Producer
</td></tr><tr><td>jndi-name</td><td>The JNDI name where the resource is stored
</td></tr><tr><td>message-listener</td><td>Configures a Consumer
</td></tr><tr><td>endpoint-factory</td><td>consumer-specific endpoint type
</td></tr><tr><td>listener</td><td>configures the user's listener
</td></tr></deftable>

<deftable>
<tr><th>class</th><th>meaning
</th></tr><tr><td>com.caucho.jms.jca.ResourceAdapterImpl</td><td>Resin's JCA adapter
for the MessageSender and MessageListener
</td></tr><tr><td>com.caucho.jms.ConnectionFactoryImpl</td><td>Resin's JMS ConnectionFactory
</td></tr><tr><td>com.caucho.jms.memory.MemoryQueue</td><td>Resin's in-memory JMS Queue
</td></tr><tr><td>com.caucho.jms.jca.MessageListenerSpec</td><td>Configuration for
the JCA adapter's Consumer
</td></tr><tr><td>com.caucho.jms.jca.ListenerEndpointFactory</td><td>Specifies the
configuration for a MessageListener
</td></tr><tr><td>example.MyListener</td><td>Example application code
</td></tr></deftable>

</s1>

</body>
</document>