Overview
Motivation
- Performance
- no need to block when performing a request
- fire-and-forget
- Reliability
- middleman
- guaranteed delivery possible
- Support for multiple senders and receivers
Aspects
- Java Message Service (JMS)
- vendor-neutral API to access enterprise messaging systems
- Message-Driven Beans
- stateless, server-side, transaction-aware components for processing asynchronous messages
Java Message Service (JMS)
Terms
- JMS client: applications that use JMS
- JMS provider: messaging system which is responsible for sending and routing of the messages
- JMS application: business system which consists of several clients and usually one provider
- MessageProducer: JMS client that sends messages
- MessageConsumer: JMS client that receives messages
- Messaging Service: is used to send messages from within EJB
Messaging Models
- Publish/Subscribe: several producers --> Topic --> several consumers
- Point-To-Point: several producers --> Queue --> one consumer
JMS API
- Locate the JMS driver: ConnectionFactory
- Create a JMS connection: Connection
- Create a JMS session: Session
- Locate the JMS destination: Destination (Queue/ Topic)
- Create JMS producer or consumer: MessageProducer/MessageConsumer
- Send or reveice message
JMS Message
- header: routing information, attributes
- properties: used for filtering (name-value pairs)
- body: the message
- types: TextMessage, MapMessage, ObjectMessage, StreamMessage, ByteMessage
Deployment Descriptor
- declare a JMS resource
- EJB 2.0
- <resource-ref>: JNDI ENC name, interface type and protocol for authorisation (e.g. name=jms/TopicFactroy, type=javax.jms.TopicConnectionFactory, auth=Container)
- <resoucre-env-ref>: name and type of the managed objects (e.g. name=jms/TicketTopic and type=javax.jms.Topic)
- EJB 2.1
- <message-destination-ref>: destination of the messages and usage (Produces, Consumes, ConsumesProduces)
Example
...
TopicConnection tConnection=null;
TopicSession tSession=null;
TopicPublisher tPublisher=null;
try{
TopicConnectionFactory tConnectionFac=
(TopicConnectionFactory)Lookup.lookup(„java:comp/env/jms“);
tConnection=tConnectionFac.createTopicConnection();
tSession=tConnection.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
Topic topic=(Topic)Lookup.lookup(„TestTopic“);
tPublisher=tSession.createPublisher(topic);
String text=“Message“;
Message message=tSession.createTextMessage(text);
tPublisher.send(message);
} catch (JMSException jes){ ...
} finally {
// close()
}
Message Driven Beans
Introduction
- does not have a home interface, local home interface, remote interface, local interface
- single, weakly typed business method (onMessage())
- do not have any return values
- cannot send exceptions back to clients
- are stateless
- can be durable or nondurable subscribers
Life Cycle
Message Driven Bean Interface
package javax.ejb;
public interface MessageDrivenBean extends javax.ejb.EnterpriseBean{
public void setMessageDrivenContext(MessageDrivenContext context)
throws EJBException;
public void ejbRemove() throws EJBException;
}
Message Driven Context
- extends EJBContext
- only setRollbackOnly(), getRollbackOnly() make sense
- getEJBHome() and getEJBLocalHome() throw a RuntimeException if invoked
- getCallerPrincipal() and isCallerInRole() throw a RuntimeException if invoked
Message Listener
package javax.jms;
public interface MessageListener {
public void onMessage(Message message);
}
Deployment Descriptor
- EJB 2.0
- declared in <message-driven>; ejb-name, ejb-class, transaction-type as session or entity bean
- <message-selector>: select which messages are processed
- <acknowledge-mode>: e.g. auto-acknowledge, dups-ok-acknowledge
- <subscription-durability>: durable or not (messages are delivered later on if a consumer is disconnected or not)
- <message-driven-destination>: type of destination (Topic/Queue)
- EJB 2.1
- <activation-config>: general declaration of properties (e.g. substitutes message-selector, acknowledge-mode and subscription-durability in EJB 2.0)
- <messaging-type>: javax.jms.MessageListener für JMS
- <messaging-destination-type>: important for COnnector-Based beans (don't use JMS)
Example
...
public abstract class MDBExample implements MessageDrivenBean, MessageListener {
...
public void ejbCreate() throws EJBException{
... // create Connection, Session, Queue
qReceiver=qSession.createReceiver(queue);
qReceiver.setMessageListener(this);
qConnection.start();
...
}
public void onMessage(Message message){
...
// if (message instanceof TextMessage){ ... }
...
}
... // setMessageDrivenContext(), ejbRemove()
}
MDB vs. Session & Entity Bean
- Entity and Session Beans should not receive messages
- impossible to write a session or entity bean that is driven by incoming messages
- receive()-method blocks java threads