JMS

From sheep
Jump to navigation Jump to search
  • Typically used as an asynchronous communication mechanism - loosely coupled
  • point to point => queue based (typically) one receiver - only one receiver receives the message
  • publish subscribe => topics => multiple receivers - all receivers receive the message
  • JMS application
    • JMS Client - application
    • JMS Provider - routing and delivery of mesages - typically one per JMS application

Message broker

  • routing
  • transactions
  • reliable delivery

Optional:

  • message priority
  • ordering
  • message transformation


Synchronous messaging

http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/jms/QueueRequestor.html

http://blogs.sun.com/fkieviet/entry/request_reply_from_an_ejb

Which discuses issues with transactions within an EJB and needing to commit the message to the JMS queue.

Sender

@Resource(mappedName="FooJMSFactory")
private ConnectionFactory cf;
@Resource(mappedName="FooTopic")
private Topic topic;

public void send() {
  Connection con = cf.createConnection();
  Session session = con.createSession(true, Session.AUTO_ACKNOWLEDGE); // should be ignored and handled by container
  MessageProducer producer = session.createProducer(topic);
  TextMessage msg = session.createTextMessage();
  msg.setText("foo");
  producer.send(msg);
  connect.close();
}

Types of message:

  1. TextMessage
  2. MapMessage
  3. ObjectMessage
  4. StreamMessage
  5. BytesMessage

MDB

Reference http://download.oracle.com/docs/cd/B25221_04/web.1013/b14428/mdb30cfg.htm

  • Must have @MessageDriven or deployment descriptor
    • mapped name element points to the queue/topic or may use ActivationConfigProperty
  • class must be public - not final
  • must have no arg public constructor
  • must no have a finalize() method
  • should implement the interface MessageListener
    • or interface for specific message provider - now JCA support JMS more flexibility - typically a different type of message parameter
  • no longer needs to implement MessageDriventBean
    • can declare the messaging-type - listener interface in the deployment descriptor
  • @ActivationConfigProperty - more advanced configuration
@MessageDriven(mappedName="jms/Topic",activationConfig=
 {@ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/TopicConFact"),
  @ActivationConfigProperty(propertyName="destinationName",           propertyValue="jms/Topic"),
  @ActivationConfigProperty(propertyName="destinationType",           propertyValue="javax.jms.Topic"),
  @ActivationConfigProperty(propertyName="messageSelector",           propertyValue="Header = ’Important’"),
  @ActivationConfigProperty(propertyName="acknowledgeMode",           propertyValue="Auto-acknowledge"),
  @ActivationConfigProperty(propertyName="subscriptionDurability",    propertyValue="Durable")
 })

public class XMessageBean implements MessageListener {
  @Resource
  private MessageDrivenContext mdc;
  
  public void onMessage(Message m) {

  // error mdc.setRollbackOnly();  

MessageListener method

  • must be public void
  • must not be final or static
  • must have only argument - Message

MessageDrivenContext

Extends EJBContext adds nothing

ActivationConfigProperty

subscriptionDurability

Durable = messages are kept until bean is available NonDurable = messages are lost if bean is unavailable

Message Linking

Allows routing to a specific MDB within same deployment

  • deployment descriptor: message-destination-link - not supported in annotations
  • can be used to define logical queues and map at deployment descriptor time
  • JCA can use to route inbound messages to MDB
  • container may bypass JMS provider - must still adhere to contract


JMS & JCA

As of JCA 1.5 there is a standard way of plugging in a JMS provider into a Application Server. Project to do so for 1.5 and 1.4 here: [1]