Previous Contents Index Next |
Sun Java System Message Queue 3.5 SP1 Java Client Developer's Guide

> ## Chapter 1
> Overview

> This chapter provides an overall introduction to Sun Java™ System Message Queue (formerly Sun™ ONE Message Queue) and to JMS concepts and programming issues of interest to developers.

> The chapter covers the following topics:

> - What Is Sun Java System Message Queue?
> - Product Editions
> - Message Queue Service Architecture
> - The JMS Programming Model
> - JMS Client Design Issues
> - JMS/J2EE Programming: Message-Driven Beans

> ##

> What Is Sun Java System Message Queue?

> The Message Queue product is a standards-based solution for reliable, asynchronous messaging for distributed applications. Message Queue is an enterprise messaging system that implements the Java™ Message Service (JMS) open standard: in fact it serves as the JMS Reference Implementation. However Message Queue is also a full-featured JMS provider with enterprise-strength features.

> The JMS specification describes a set of messaging semantics and behaviors, and an application programming interface (API), that provide a common way for Java language applications to create, send, receive, and read messages in a distributed environment (see The JMS Programming Model). In addition to supporting Java messaging applications, Message Queue also provides a C language interface to the Message Queue service (the Message Queue C-API).

> With Sun Java System Message Queue software, processes running on different platforms and operating systems can connect to a common Message Queue service to send and receive information. Application developers are free to focus on the business logic of their applications, rather than on the low-level details of how their applications reliably communicate across a network.

> Message Queue has features that exceed the minimum requirements of the JMS specification. Among these features are the following:

> Centralized administration. Provides both command-line and GUI tools for administering a Message Queue service and managing application-dependent entities, such as destinations, transactions, durable subscriptions, and security. Message Queue also supports remote monitoring of the Message Queue service.

> Scalable message service. Allows you to service increasing numbers of Message Queue clients (components or applications) by balancing the load among a number of Message Queue message server components (brokers) working in tandem (multi-broker cluster).

> Client connection failover. Automatically restores a failed client connection to a Message Queue message server.

> Tunable performance. Lets you increase performance of the Message Queue service when less reliability of delivery is acceptable.

> Multiple transports. Supports the ability of Message Queue clients to communicate with the Message Queue message server over a number of different transports, including TCP and HTTP, and using secure (SSL) connections.

> JNDI support. Supports both file-based and LDAP implementations of the Java Naming and Directory Interface (JNDI) as object stores and user repositories.

> SOAP messaging support. Supports creation and delivery of SOAP messages—messages that conform to the Simple Object Access Protocol (SOAP) specification— via JMS messaging. SOAP allows for the exchange of structured XML data between peers in a distributed environment. See the Chapter 6, "Working With SOAP Messages" for more information.

> See the Message Queue Administration Guide for documentation of JMS compliance-related issues.

> ##

> Product Editions

> Sun Java System Message Queue is available in two editions: Platform and Enterprise—each corresponding to a different feature set and licensed capacity, as described below. (Instructions for upgrading Message Queue from one edition to another are in the Message Queue Installation Guide.)

> ### Platform Edition

> This edition can be downloaded free from the Sun website and is also bundled with the Sun Java™ System Application Server platform. The Platform Edition places no limit on the number of client connections supported by the Message Queue message server. It comes with two licenses, as described below:

> - a basic license. This license provides basic JMS support (it’s a full JMS provider), but does not include such enterprise features as load balancing (multi-broker message service), HTTP/HTTPS connections, secure connection services, scalable connection capability, client connection failover, queue delivery to multiple consumers, remote message-based monitoring, and C-API support. The license has an unlimited duration, and can therefore be used in less demanding production environments.
> - a 90-day trial enterprise license. This license includes all enterprise features (such as support for multi-broker message services, HTTP/HTTPS connections, secure connection services, scalable connection capability, client connection failover, queue delivery to multiple consumers, remote message-based monitoring, and C-API support) not included in the basic license. However, the license has a limited 90-day duration enforced by the software, making it suitable for evaluating the enterprise features available in the Enterprise Edition of the product (see Enterprise Edition).

> Note | The 90-day trial license can be enabled by starting the Message Queue service—a broker instance—with the -license command line option (see the Message Queue Administration Guide) and passing “try” as the license to use: imqbrokerd -license try You must use this option each time you start the broker instance, otherwise it defaults back to the basic Platform Edition license.

> ### Enterprise Edition

> This edition is for deploying and running messaging applications in a production environment. It includes support for multi-broker message services, HTTP/HTTPS connections, secure connection services, scalable connection capability, client connection failover, queue delivery to multiple consumers, remote message-based monitoring, and C-API support. You can also use the Enterprise Edition for developing, debugging, and load testing messaging applications and components. The Enterprise Edition has an unlimited duration license that places no limit on the number of brokers in a multi-broker message service, but is based on the number of CPUs that are used.

> Note | For all editions of Message Queue, a portion of the product—the client runtime—can be freely redistributed for commercial use. All other files in the product cannot be redistributed. The portion that can be freely redistributed allows a licensee to develop a Java client application (one which can be connected to a Message Queue service) that can be sold to a third party without incurring any Message Queue licensing fees. The third party will either need to purchase Message Queue to access a Message Queue service or make a connection to yet another party that has a Message Queue service installed and running.

> ##

> Message Queue Service Architecture

> This section briefly describes the main parts of a Message Queue service. While as a developer, you do not need to be familiar with the details of all of these parts or how they interact, a high-level understanding of the basic architecture will help you understand features of the system that impact client application design and development.

> The main parts of a Message Queue service, shown in Figure 1-1, are the following:

> Message Queue server The Message Queue server is the heart of a messaging system. It consists of one or more brokers which provide delivery services for the system. These services include connections to clients, message routing and delivery, persistence, security, and logging. The message server maintains physical destinations to which clients send messages, and from which the messages are delivered to consuming clients. The Message Queue server is described in detail in the Message Queue Administration Guide.

> Message Queue client runtime The Message Queue client runtime provides clients with an interface to the Message Queue service—it supplies clients with all the JMS programming objects introduced in The JMS Programming Model. It supports all operations needed for clients to send messages to destinations and to receive messages from such destinations. The Message Queue client runtime is described in detail in Chapter 4, "Configuring the Message Queue Client Runtime."

> Figure 1-1 Message Queue System Architecture

> Message Queue administered objects Administered Objects encapsulate provider-specific implementation and configuration information in objects that are used by Message Queue clients. Administered objects are generally created and configured by an administrator, stored in a name service, accessed by clients through standard JNDI lookup code, and then used in a provider-independent manner. They can also be instantiated by clients, in which case they are used in a provider-specific manner. Configuration of the client runtime is performed through administered object attributes, as described in Chapter 4, "Configuring the Message Queue Client Runtime."

> Message Queue administration Message Queue provides a number of administration tools for managing a Message Queue service. These tools are used to manage the message server, create and store administered objects, manage security, manage messaging application resources, and manage persistent data. These tools are generally used by administrators and are described in the Message Queue Administration Guide.

> ##

> The JMS Programming Model

> This section briefly describes the programming model of the JMS specification. It is meant as a review of the most important concepts and terminology used in programming JMS clients.

> ### JMS Programming Interface

> In the JMS programming model, JMS clients (components or applications) interact using a JMS application programming interface (API) to send and receive messages. This section introduces the objects that implement the JMS API and that are used to set up a client for delivery of messages (see JMS Client Setup Operations). The main interface objects are shown in Figure 1-2 and described in the following paragraphs.

> #### Message

> In the Message Queue product, data is exchanged using JMS messages—messages that conform to the JMS specification. According to the JMS specification, a message is composed of three parts: a header, properties, and a body.

> Properties are optional—they provide values that clients can use to filter messages. A body is also optional—it contains the actual data to be exchanged.

> Figure 1-2 JMS Programming Objects

> [D]

> ##### Header

> A header is required of every message. Header fields contain values used for routing and identifying messages.

> Some header field values are set automatically by Message Queue during the process of producing and delivering a message, some depend on settings of message producers specified when the message producers are created in the client, and others are set on a message by message basis by the client using JMS APIs. The following table lists the header fields defined (and required) by JMS, as well as how they are set.

> Table 1-1 JMS-Defined Message Header

> Header Field | Set By: | Default
> --- | --- | ---
> JMSDestination | Client, for each message producer or message |
> JMSDeliveryMode | Client, for each message producer or message | Persistent
> JMSExpiration | Client, for each message producer or message | time to live is 0 (no expiration)
> JMSPriority | Client, for each message producer or message | 4 (normal)
> JMSMessageID | Provider, automatically |
> JMSTimestamp | Provider, automatically |
> JMSRedelivered | Provider, automatically |
> JMSCorrelationID | Client, for each message |
> JMSReplyTo | Client, for each message |
> JMSType | Client, for each message |

> ##### Properties

> When data is sent between two processes, other information besides the payload data can be sent with it. These descriptive fields, or properties, can provide additional information about the data, including which process created it, the time it was created, and information that uniquely identifies the structure of each piece of data. Properties (which can be thought of as an extension of the header) consist of property name and property value pairs, as specified by JMS client code.

> Having registered an interest in a particular destination, consuming clients can fine-tune their selection by specifying certain property values as selection criteria. For instance, a client might indicate an interest in Payroll messages (rather than Facilities) but only Payroll items concerning part-time employees located in New Jersey. Messages that do not meet the specified criteria are not delivered to the consumer.

> ##### Message Body Types

> JMS specifies six classes (or types) of messages that a JMS provider must support, as described in the following table:

> Table 1-2 Message Body Types

> Type | Description
> --- | ---
> Message | A message without a message body.
> StreamMessage | A message whose body contains a stream of Java primitive values. It is filled and read sequentially.
> MapMessage | A message whose body contains a set of name-value pairs. The order of entries is not defined.
> TextMessage | A message whose body contains a Java string, for example an XML message.
> ObjectMessage | A message whose body contains a serialized Java object.
> BytesMessage | A message whose body contains a stream of uninterpreted bytes.

> #### Destination

> A Destination is a JMS administered object (see Administered Objects) that identifies a physical destination in a JMS message service. A physical destination is a JMS message service entity to which producers send messages and from which consumers receive messages. The message service provides the routing and delivery for messages sent to a physical destination. A Destination administered object encapsulates provider-specific naming conventions for physical destinations. This lets clients be provider independent.

> #### ConnectionFactory

> A ConnectionFactory is a JMS administered object (see Administered Objects) that encapsulates provider-specific connection configuration information. A client uses it to create a connection over which messages are delivered. JMS administered objects can either be acquired through a Java Naming and Directory Service (JNDI) lookup or directly instantiated using provider-specific classes.

> #### Connection

> A Connection is a client’s active connection to a JMS message service. Both allocation of communication resources and authentication of a client take place when a connection is created. Hence it is a relatively heavy-weight object, and most clients do all their messaging with a single connection. A connection is used to create sessions.

> #### Session

> A Session is a single-threaded context for producing and consuming messages. While there is no restriction on the number of threads that can use a session, the session should not be used concurrently by multiple threads. It is used to create the message producers and consumers that send and receive messages, and defines a serial order for the messages it delivers. A session supports reliable delivery through a number of acknowledgement options or by using transactions. A transacted session can combine a series of sequential operations into a single transaction that can span a number of producers and consumers.

> #### Message Producer

> A client uses a MessageProducer to send messages to a physical destination. A MessageProducer object is normally created by passing a Destination administered object to a session’s methods for creating a message producer. (If you create a message producer that does not reference a specific destination, then you must specify a destination for each message you produce.) A client can specify a default delivery mode, priority, and time-to-live for a message producer. These values govern all messages sent by a producer, except when explicitly over-ridden.

> #### Message Consumer

> A client uses a MessageConsumer to receive messages from a physical destination. It is created by passing a Destination administered object to a session’s methods for creating a message consumer. A message consumer can have a message selector that allows the message service to deliver only those messages that match the selection criteria. A message consumer can support either synchronous or asynchronous consumption of messages (see Message Consumption: Synchronous and Asynchronous).

> #### Message Listener

> A client uses a MessageListener object to consume messages asynchronously. The MessageListener is registered with a message consumer. A client consumes a message when a session thread invokes the onMessage() method of the MessageListener object.

> ### Administered Objects

> The JMS specification facilitates provider-independent clients by specifying administered objects that encapsulate provider-specific configuration information.

> Two of the objects described in the The JMS Programming Model depend on how a JMS provider implements a JMS message service. The connection factory object depends on the underlying protocols and mechanisms used by the provider to deliver messages, and the destination object depends on the specific naming conventions and capabilities of the physical destinations used by the provider.

> Normally these provider-specific characteristics would make client code dependent on a specific JMS implementation. However, the JMS specification requires that provider-specific implementation and configuration information be encapsulated in connection factory and destination objects that can then be accessed in a standardized, non-provider-specific way.

> Administered objects are created and configured by an administrator, stored in a name service, and accessed by clients through standard Java Naming and Directory Service (JNDI) lookup code. Using administered objects in this way makes client code provider-independent.

> The two types of administered objects, connection factories and destinations, encapsulate provider-specific information, but they have very different uses within a client. A connection factory is used to create connections to the message server, while destination objects are used to identify physical destinations.

> For more information on administered objects, see Chapter 3, "Using Administered Objects."

> ### JMS Client Setup Operations

> There is a general approach within the JMS programming model for setting up a JMS client to produce or consume messages. It uses the JMS programming interface objects described in the previous section.

> The general procedures for producing and consuming messages are introduced below. The procedures have a number of common steps which need not be duplicated if a client is both producing and consuming messages.

> ##### To Set Up a Client to Produce Messages

> 1. Use JNDI to find a ConnectionFactory object. (You can also directly instantiate a ConnectionFactory object and set its attribute values.)
> 2. Use the ConnectionFactory object to create a Connection object.
> 3. Use the Connection object to create one or more Session objects.
> 4. Use JNDI to find one or more Destination objects. (You can also directly instantiate a Destination object and set its name attribute.)
> 5. Use a Session object and a Destination object to create any needed MessageProducer objects. (You can create a MessageProducer object without specifying a Destination object, but then you have to specify a Destination object for each message that you produce.)

> At this point the client has the basic setup needed to produce messages.

> ##### To Set Up a Client to Consume Messages

> 1. Use JNDI to find a ConnectionFactory object. (You can also directly instantiate a ConnectionFactory object and set its attribute values.)
> 2. Use the ConnectionFactory object to create a Connection object.
> 3. Use the Connection object to create one or more Session objects.
> 4. Use JNDI to find one or more Destination objects. (You can also directly instantiate a Destination object and set its name attribute.)
> 5. Use a Session object and a Destination object to create any needed MessageConsumer objects.
> 6. If needed, instantiate a MessageListener object and register it with a MessageConsumer object.
> 7. Tell the Connection object to start delivery of messages. This allows messages to be delivered to the client for consumption.

> At this point the client has the basic setup needed to consume messages.

> ##

> JMS Client Design Issues

> This section is a review of a number of JMS messaging issues that impact JMS client design.

> ### Programming Domains

> JMS supports two distinct message delivery models: point-to-point and publish/subscribe.

> Point-to-Point (Queue Destinations) A message is delivered from a producer to one consumer. In this delivery model, the destination is a queue. Messages are first delivered to the queue destination, then delivered from the queue, one at a time, depending on the queue’s delivery policy (see Chapter 2 in the Message Queue Administration Guide), to one of the consumers registered for the queue. Any number of producers can send messages to a queue destination, but each message is guaranteed to be delivered to—and successfully consumed by—only one consumer. If there are no consumers registered for a queue destination, the queue holds messages it receives, and delivers them when a consumer registers for the queue.

> Publish/Subscribe (Topic destinations) A message is delivered from a producer to any number of consumers. In this delivery model, the destination is a topic. Messages are first delivered to the topic destination, then delivered to all active consumers that have subscribed to the topic. Any number of producers can send messages to a topic destination, and each message can be delivered to any number of subscribed consumers. Topic destinations also support the notion of durable subscriptions. A durable subscription represents a consumer that is registered with the topic destination but can be inactive at the time that messages are delivered. When the consumer subsequently becomes active, it receives the messages. If there are no consumers registered for a topic destination, the topic does not hold messages it receives, unless it has durable subscriptions for inactive consumers.

> These two message delivery models are handled using different API objects—with slightly different semantics—representing different programming domains, as shown in Table 1-3.

> Table 1-3 JMS Programming Objects

> Base Type (Unified Domain) | Point-to-Point Domain | Publish/Subscribe Domain
> --- | --- | ---
> Destination (Queue or Topic)1 | Queue | Topic
> ConnectionFactory | QueueConnectionFactory | TopicConnectionFactory
> Connection | QueueConnection | TopicConnection
> Session | QueueSession | TopicSession
> MessageProducer | QueueSender | TopicPublisher
> MessageConsumer | QueueReceiver | TopicSubscriber

> 1Depending on programming approach, you might specify a particular destination type.

> You can program both point-to-point and publish/subscribe messaging using the unified domain objects that conform to the JMS 1.1 specification (shown in the first column of Table 1-3). The JMS 1.1 specification, provides a simplified approach to JMS client programming as compared to JMS 1.02. In particular, a client can perform both point-to-point and publish/subscribe messaging over the same connection and within the same session, and can include both queues and topics in the same transaction.

> In short, a client developer need not make a choice between the separate point-to-point and publish/subscribe programming domains of JMS 1.0.2, opting instead for the simpler, unified domain approach of JMS 1.1. This is the preferred approach, however the JMS 1.1 specification continues to support the separate JMS 1.02 programming domains. (In fact, the example applications included with the Message Queue product as well as the code examples provided in this book all use the separate JMS 1.02 programming domains.)

> Note | Developers of applications that run in the Sun Java System Application Server 7 environment are limited to using the JMS 1.0.2 API. This is because Sun Java System Application Server 7 complies with the J2EE 1.3 specification, which supports only JMS 1.0.2. Any JMS messaging performed in servlets and EJBs—including message-driven beans (see Message-Driven Beans)—must be based on the domain-specific JMS APIs.

> ### JMS Provider Independence

> JMS specifies the use of administered objects (see Administered Objects) to support the development of clients that are portable to other JMS providers. Administered objects allow clients to use logical names to look up and reference provider-specific objects. In this way application does not need to know specific naming or addressing syntax or configurable properties used by a provider. This makes the code provider-independent.

> Administered objects are Message Queue system objects created and configured by a Message Queue administrator. These objects are placed in a JNDI directory service, and a JMS client accesses them using a JNDI lookup.

> Message Queue administered objects can also be instantiated by the client, rather than looked up in a JNDI directory service. This has the drawback of requiring the application developer to use provider-specific APIs. It also undermines the ability of a Message Queue administrator to successfully control and manage a Message Queue service.

> For more information on administered objects, see Chapter 3, "Using Administered Objects."

> ### Client Identifiers

> JMS providers must support the notion of a client identifier, which associates a JMS client’s connection to a message service with state information maintained by the message service on behalf of the client. By definition, a client identifier is unique, and applies to only one user at a time. Client identifiers are used in combination with a durable subscription name (see Publish/Subscribe (Topic destinations)) to make sure that each durable subscription corresponds to only one user.

> The JMS specification allows client identifiers to be set by the client through an API method call, but recommends setting it administratively using a connection factory administered object (see Administered Objects). If hard wired into a connection factory, however, each user would then need an individual connection factory to have a unique identity.

> Message Queue provides a way for the client identifier to be both ConnectionFactory and user specific using a special variable substitution syntax that you can configure in a ConnectionFactory object (see Client Identification). When used this way, a single ConnectionFactory object can be used by multiple users who create durable subscriptions, without fear of naming conflicts or lack of security. A user's durable subscriptions are therefore protected from accidental erasure or unavailability due to another user having set the wrong client identifier.

> For deployed applications, the client identifier must either be programmatically set by the client, using the JMS API, or administratively configured in the ConnectionFactory objects used by the client.

> In any case, in order to create a durable subscription, a client identifier must be either programmatically set by the client, using the JMS API, or administratively configured in the ConnectionFactory objects used by the client.

> ### Reliable Messaging

> JMS defines two delivery modes:

> Persistent messages These messages are guaranteed to be delivered and successfully consumed once and only once. Reliability is at a premium for such messages.

> Non-persistent messages These messages are guaranteed to be delivered at most once. Reliability is not a major concern for such messages.

> There are two aspects of assuring reliability in the case of persistent messages. One is to assure that their delivery to and from a message service is successful. The other is to assure that the message service does not lose persistent messages before delivering them to consumers.

> #### Acknowledgements/Transactions

> Reliable messaging depends on guaranteeing the successful delivery of persistent messages to and from a destination. This can be achieved using either of two general mechanisms supported by a Message Queue session: acknowledgements or transactions. In the case of transactions, these can either be local or distributed, under the control of a distributed transaction manager.

> ##### Acknowledgements

> A session can be configured to use acknowledgements to assure reliable delivery.

> In the case of a producer, this means that the message service acknowledges delivery of a persistent message to its destination before the producer’s send() method returns. In the case of a consumer, this means that the client acknowledges delivery and consumption of a persistent message from a destination before the message service deletes the message from that destination.

> ##### Local Transactions

> A session can also be configured as transacted, in which case the production and/or consumption of one or more messages can be grouped into an atomic unit—a transaction. The JMS API provides methods for initiating, committing, or rolling back a transaction.

> As messages are produced or consumed within a transaction, the broker tracks the various sends and receives, completing these operations only when the client issues a call to commit the transaction. If a particular send or receive operation within the transaction fails, an exception is raised. The application can handle the exception by ignoring it, retrying the operation, or rolling back the entire transaction. When a transaction is committed, all the successful operations are completed. When a transaction is rolled back, all successful operations are cancelled.

> The scope of a local transaction is always a single session. That is, one or more producer or consumer operations performed in the context of a single session can be grouped into a single local transaction.

> Since transactions span only a single session, you cannot have an end-to-end transaction encompassing both the production and consumption of a message. (In other words, the delivery of a message to a destination and the subsequent delivery of the message to a client cannot be placed in a single transaction.)

> ##### Distributed Transactions

> Message Queue also supports distributed transactions. That is, the production and consumption of messages can be part of a larger, distributed transaction that includes operations involving other resource managers, such as database systems. In distributed transactions, a distributed transaction manager tracks and manages operations performed by multiple resource managers (such as a message service and a database manager) using a two-phase commit protocol defined in the Java Transaction API (JTA), XA Resource API specification. In the Java world, interaction between resource managers and a distributed transaction manager are described in the JTA specification.

> Support for distributed transactions means that messaging clients can participate in distributed transactions through the XAResource interface defined by JTA. This interface defines a number of methods for implementing two-phase commit. While the API calls are made on the client side, the Message Queue broker tracks the various send and receive operations within the distributed transaction, tracks the transactional state, and completes the messaging operations only in coordination with a distributed transaction manager—provided by a Java Transaction Service (JTS).

> As with local transactions, the client can handle exceptions by ignoring them, retrying operations, or rolling back an entire distributed transaction.

> Message Queue implements support for distributed transactions through an XA connection factory, which lets you create XA connections, which in turn lets you create XA sessions (see The JMS Programming Model). In addition, support for distributed transactions requires either a third party JTS or a J2EE-compliant Application Server (that provides JTS).

> #### Persistent Storage

> The other important aspect of reliability is assuring that once persistent messages are delivered to their destinations, the message service does not lose them before they are delivered to consumers. This means that upon delivery of a persistent message to its destination, the message service must place it in a persistent data store. If the message service goes down for any reason, it can recover the message and deliver it to the appropriate consumers. While this adds overhead to message delivery, it also adds reliability.

> A message service must also store durable subscriptions. This is because to guarantee delivery in the case of topic destinations, it is not sufficient to recover only persistent messages. The message service must also recover information about durable subscriptions for a topic, otherwise it would not be able to deliver a message to durable subscribers when they become active.

> Messaging applications that are concerned about guaranteeing delivery of persistent messages must either employ queue destinations or employ durable subscriptions to topic destinations.

> ### Performance Trade-offs

> The more reliable the delivery of messages, the more overhead and bandwidth are required to achieve it. The trade-off between reliability and performance is a significant design consideration. You can maximize performance and throughput by choosing to produce and consume non-persistent messages. On the other hand, you can maximize reliability by producing and consuming persistent messages in a transaction using a transacted session. Between these extremes are a number of options, depending on the needs of an application, including the use of Message Queue-specific persistence and acknowledgement properties (see Managing Reliability and Performance).

> ### Message Consumption: Synchronous and Asynchronous

> There are two ways a JMS client can consume messages: either synchronously or asynchronously.

> In synchronous consumption, a client gets a message by invoking the receive() method of a MessageConsumer object. The client thread blocks until the method returns. This means that if no message is available, the client blocks until a message does become available or until the receive() method times out (if it was called with a time-out specified). In this model, a client thread can only consume messages one at a time (synchronously).

> In asynchronous consumption, a client registers a MessageListener object with a message consumer. The message listener is like a call-back object. A client consumes a message when the session invokes the onMessage() method of the MessageListener object. In this model, the client thread does not block (message is asynchronously consumed) because the thread listening for and consuming the message belongs to the Message Queue client runtime.

> ### Message Selection

> JMS provides a mechanism by which a message service can perform message filtering and routing based on criteria placed in message selectors. A producing client can place application-specific properties in the message, and a consuming client can indicate its interest in messages using selection criteria based on such properties. This simplifies the work of the client and eliminates the overhead of delivering messages to clients that don’t need them. However, it adds some additional overhead to the message service processing the selection criteria. Message selector syntax and semantics are outlined in the JMS specification.

> ### Message Order and Priority

> In general, all messages sent to a destination by a single session are guaranteed to be delivered to a consumer in the order they were sent. However, if they are assigned different priorities, a messaging system will attempt to deliver higher priority messages first.

> Beyond this, the ordering of messages consumed by a client can have only a rough relationship to the order in which they were produced. This is because the delivery of messages to a number of destinations and the delivery from those destinations can depend on a number of issues that affect timing, such as the order in which the messages are sent, the sessions from which they are sent, whether the messages are persistent, the lifetime of the messages, the priority of the messages, the message delivery policy of queue destinations (see the Message Queue Administration Guide), and message service availability.

> ##

> JMS/J2EE Programming: Message-Driven Beans

> In addition to the general client programming model introduced in The JMS Programming Model, there is a more specialized adaptation of JMS used in the context of Java 2 Enterprise Edition (J2EE) applications. This specialized JMS client is called a message-driven bean and is one of a family of Enterprise JavaBeans (EJB) components specified in the EJB 2.0 Specification (http://java.sun.com/products/ejb/docs.html).

> The need for message-driven beans arises out of the fact that other EJB components (session beans and entity beans) can only be called synchronously. These EJB components have no mechanism for receiving messages asynchronously, since they are only accessed through standard EJB interfaces.

> However, asynchronous messaging is a requirement of many enterprise applications. Most such applications require that server-side components be able to communicate and respond to each other without tying up server resources. Hence, the need for an EJB component that can receive messages and consume them without being tightly coupled to the producer of the message. This capability is needed for any application in which server-side components must respond to application events. In enterprise applications, this capability must also scale under increasing load.

> ### Message-Driven Beans

> A message-driven bean (MDB) is a specialized EJB component supported by a specialized EJB container (a software environment that provides distributed services for the components it supports).

> Message-driven Bean The MDB is a JMS message consumer that implements the JMS MessageListener interface. The onMessage method (written by the MDB developer) is invoked when a message is received by the MDB container. The onMessage() method consumes the message, just as the onMessage() method of a standard MessageListener object would. You do not remotely invoke methods on MDBs—like you do on other EJB components—therefore there are no home or remote interfaces associated with them. The MDB can consume messages from a single destination. The messages can be produced by standalone JMS applications, JMS components, EJB components, or Web components, as shown in Figure 1-3.

> Figure 1-3 Messaging with MDBs

> [D]

> MDB Container The MDB is supported by a specialized EJB container, responsible for creating instances of the MDB and setting them up for asynchronous consumption of messages. This involves setting up a connection with the message service (including authentication), creating a pool of sessions associated with a given destination, and managing the distribution of messages as they are received among the pool of sessions and associated MDB instances. Since the container controls the life-cycle of MDB instances, it manages the pool of MDB instances so as to accommodate incoming message loads.

> Associated with an MDB is a deployment descriptor that specifies the JNDI lookup names for the administered objects used by the container in setting up message consumption: a connection factory and a destination. The deployment descriptor might also include other information that can be used by deployment tools to configure the container. Each such container supports instances of only a single MDB.

> ### J2EE Application Server Support

> In J2EE architecture (see the J2EE Platform Specification located at http://java.sun.com/j2ee/download.html#platformspec), EJB containers are hosted by J2EE application servers. An application server provides resources needed by the various containers: transaction managers, persistence managers, name services, and, in the case of messaging and MDBs, a JMS provider.

> In Sun Java System Application Server, JMS messaging resources are provided by Sun Java System Message Queue:

> - For Sun Java System Application Server 7, a Message Queue messaging system is integrated into the application server as its native JMS provider.
> - For the Sun J2EE 1.4 Application Server, Message Queue is plugged into the application server as an embedded JMS resource adapter (see Appendix F, “The MQ Resource Adapter,” in the Message Queue Administration Guide for details).
> - For future releases of Application Server, Message Queue will be plugged into the application server using standard resource adapter deployment and configuration methods.

> Previous Contents Index Next

> Copyright 2004 Sun Microsystems, Inc. All rights reserved.