|
| |
Find this tutorial in: /usr/local/resin/webapps/resin-doc/ejb/tutorial/ejb-messaging-queue
Try the Tutorial
EJB message beans are used to process message received through JMS. The
message-driven bean server processes messages as they become available. The
Resin-EE server calls the bean's onMessage()
method with each new message.
In this example, a simple message-driven bean is created and deployed, and a
simple servlet is used to send messages.
EJB message beans use the facilities provided by JMS.
JMS, the Java Messaging Service, is an elaborated queueing system.
Clients add messages to the queues and servers remove the
messages.
There are two types of messaging supported by JMS. A Queue is used
when there is one consumer of the message. A sender sends the message, and the
message remains in the queue until a consumer reads the message or the
message times out. A Topic is used when there may be more than one
subscriber. The server distributes the message to all of the registered
subscribers.
The server needs to have both a ConnectionFactory and a
Destination. Destinations are either Queue or Topic objects and
ConnectionFactories are either
QueueConnectionFactory or TopicConnectionFactory.
Like other JNDI resources, JMS objects are configured with resource
directives. In this example, the configuration is in web.xml, which
creates the JMS resources specifically for the web-app. The JMS objecs could
just as easily be created at the host or server level, and thus shared in
common with many web applications.
See it in: WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
...
<!--
- JMS
-->
<resource jndi-name="jms/queue-connection-factory"
type='com.caucho.jms.JVMQueueConnectionFactory'/>
<resource jndi-name="jms/queue"
type='com.caucho.jms.memory.MemoryQueue'/>
...
|
Resin-EE's EJB message-bean implementation can use any
JMS implementation which conforms to the specifications. Resin-EE
also includes a basic memory-based JMS
implementation.
The following are the factories for Resin-EE's JMS objects:
Class | Description
|
com.caucho.jms.JVMQueueConnectionFactory | The connection factory for queues.
|
com.caucho.jms.memory.MemoryQueue | A memory-based queue.
|
com.caucho.jms.JVMTopicConnectionFactory | The connection factory for topics.
|
com.caucho.jms.memory.MemoryTopic | A memory-based topic.
|
The message-driven bean server processes messages as they become
available. The Resin-EE server calls a message-driven bean's
onMessage() method with each new message.
Unlike session and entity beans, EJB message-driven beans are implemented
with a single class. They do not have a separate interface, implementation
class, and home class.
See it in: WEB-INF/classes/example/SimpleMessageBean.java
package example;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJBException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class SimpleMessageBean implements MessageDrivenBean, MessageListener {
static protected final Logger log =
Logger.getLogger(SimpleMessageBean.class.getName());
public void ejbCreate()
throws EJBException
{
log.fine("ejbCreate()");
}
public void setMessageDrivenContext(MessageDrivenContext cxt)
throws EJBException
{
log.fine("setMessageDrivenContext()");
}
public void onMessage(Message msg)
{
// process the message
String text = null;
if (msg instanceof TextMessage) {
try {
text = ((TextMessage) msg).getText();
} catch (Exception ex) {
log.log(Level.WARNING,null,ex);
}
}
else {
text = msg.toString();
}
log.fine("onMessage(): " + text);
}
public void ejbRemove()
throws EJBException
{
log.fine("ejbRemove()");
}
}
|
The message bean is described in a deployment descriptor. The Resin-EE ejb
server will process an file in the WEB-INF directory with the ".ejb"
extension as an ejb deployment descriptor.
In this case, the file WEB-INF/message.ejb is used to configure
the message-driven bean SimpleMessageBean.
See it in: WEB-INF/message.ejb
<ejb-jar xmlns="http://caucho.com/ns/resin">
<enterprise-beans>
<message-driven>
<ejb-name>SimpleMessageBean</ejb-name>
<ejb-class>example.SimpleMessageBean</ejb-class>
<destination>jms/queue</destination>
</message-driven>
</enterprise-beans>
</ejb-jar>
|
The Resin-EE ejb server is responsible for recognizing the
message.ejb file and deploying the bean.
See it in: WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
...
<ejb-server config-directory="WEB-INF">
<jms-connection-factory>jms/queue-connection-factory</jms-connection-factory>
</ejb-server>
|
The client creates messages and sends them to a destination.
A client needs to:
- Get a Destination and ConnectionFactory, usually with a lookup using JNDI
- Create a Sender (or Publisher for Topics)
- Create a message
- Send the message
For this example, a simple servlet is used to perform the above steps,
sending 5 messages.
The JNDI lookup is done in the init() method, and the resulting
objects are stored as member variables:
See it in: WEB-INF/classes/example/MessageSenderServlet.java
...
Queue _queue;
QueueConnectionFactory _factory;
public void init()
throws ServletException
{
super.init();
// look up the objects.
try {
Context env = (Context) new InitialContext().lookup("java:comp/env");
_queue = (Queue) env.lookup("jms/queue");
if (_queue == null)
throw new ServletException("`java:comp/env/jms/queue' lookup failed");
_factory = (QueueConnectionFactory) env.lookup("jms/queue-connection-factory");
if (_factory == null)
throw new ServletException("`java:comp/env/jms/queue-connection-factory' lookup failed");
} catch (NamingException ex) {
throw new ServletException(ex);
}
}
...
|
The 5 messages are sent in the service() method:
See it in: WEB-INF/classes/example/MessageSenderServlet.java
...
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException
{
int count = 5;
try {
QueueConnection connection = _factory.createQueueConnection();
QueueSession jmsSession = connection.createQueueSession(false, 0);
QueueSender sender = jmsSession.createSender(_queue);
for (int i = 1; i <= count; i++) {
String text = "hello, world: message #" + String.valueOf(i);
sendMessage(jmsSession,sender,text);
}
} catch (JMSException ex) {
throw new ServletException(ex);
}
PrintWriter out = response.getWriter();
out.print("Sent " + String.valueOf(count) + " messages.");
}
protected void sendMessage(QueueSession jmsSession, QueueSender sender, String text)
throws JMSException
{
// create the message
Message message = jmsSession.createTextMessage(text);
// send the message
sender.send(message);
log.fine("Sent message: " + text);
}
...
|
Logging is an extremely useful debugging aid when working with JMS. In this
case, logging is used in both the message-driven bean and the sender.
The log configuration in web.xml is used to log both the class
name and the message in the file WEB-INF/debug.log.
See it in: WEB-INF/web.xml
<web-app xmlns="http://caucho.com/ns/resin">
<log name="example" level="fine" path="WEB-INF/debug.log" timestamp="[%M:%S.%s] "
format="${log.loggerName} ${log.message}"/>
...
</web-app>
|
The use of the JDK logging API is quite straightforward, here is an example
from SimpleMessageBean:
See it in: WEB-INF/classes/example/SimpleMessageBean.java
public class SimpleMessageBean implements MessageDrivenBean, MessageListener {
static protected final Logger log =
Logger.getLogger(SimpleMessageBean.class.getName());
...
public void onMessage(Message msg)
{
...
log.fine("onMessage(): " + text);
}
|
The WEB-INF/debug.xml log shows the results of using the MessageSenderServlet:
[41:41.618] example.SimpleMessageBean setMessageDrivenContext()
[41:41.618] example.SimpleMessageBean ejbCreate()
[41:41.638] example.SimpleMessageBean onMessage(): hello, world: message #1
[41:41.638] example.MessageSenderServlet Sent message: hello, world: message #1
[41:41.638] example.SimpleMessageBean onMessage(): hello, world: message #2
[41:41.638] example.MessageSenderServlet Sent message: hello, world: message #2
[41:41.638] example.SimpleMessageBean onMessage(): hello, world: message #3
[41:41.638] example.MessageSenderServlet Sent message: hello, world: message #3
[41:41.638] example.SimpleMessageBean onMessage(): hello, world: message #4
[41:41.638] example.MessageSenderServlet Sent message: hello, world: message #4
[41:41.638] example.SimpleMessageBean onMessage(): hello, world: message #5
[41:41.638] example.MessageSenderServlet Sent message: hello, world: message #5
|
Try the Tutorial
Copyright © 1998-2006 Caucho Technology, Inc. All rights reserved.
Resin® is a registered trademark,
and HardCoretm and Quercustm are trademarks of Caucho Technology, Inc. | |
|