Asynchronous Messaging
Jump to navigation
Jump to search
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)
- EJB 2.0
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