2. Using the Tutorial Examples 3. Getting Started with Web Applications 5. JavaServer Pages Technology 7. JavaServer Pages Standard Tag Library 10. JavaServer Faces Technology 11. Using JavaServer Faces Technology in JSP Pages 12. Developing with JavaServer Faces Technology 13. Creating Custom UI Components 14. Configuring JavaServer Faces Applications 15. Internationalizing and Localizing Web Applications 16. Building Web Services with JAX-WS 17. Binding between XML Schema and Java Classes 19. SOAP with Attachments API for Java 21. Getting Started with Enterprise Beans 23. A Message-Driven Bean Example 24. Introduction to the Java Persistence API 25. Persistence in the Web Tier 26. Persistence in the EJB Tier 27. The Java Persistence Query Language 28. Introduction to Security in the Java EE Platform 29. Securing Java EE Applications 31. The Java Message Service API How Does the JMS API Work with the Java EE Platform? Point-to-Point Messaging Domain Publish/Subscribe Messaging Domain Programming with the Common Interfaces Writing Simple JMS Client Applications A Simple Example of Synchronous Message Receives Writing the Client Programs for the Synchronous Receive Example Creating JMS Administered Objects for the Synchronous Receive Example Compiling and Packaging the Clients for the Synchronous Receive Example Running the Clients for the Synchronous Receive Example A Simple Example of Asynchronous Message Consumption Writing the Client Programs for the Asynchronous Receive Example Compiling and Packaging theAsynchConsumer Client Running the Clients for the Asynchronous Receive Example A Simple Example of Browsing Messages in a Queue Writing the Client Program for the Queue Browser Example Compiling and Packaging theMessageBrowser Client Running the Clients for the Queue Browser Example Running JMS Client Programs on Multiple Systems Creating Administered Objects for Multiple Systems Editing, Recompiling, Repackaging, and Running the Programs Deleting the Connection Factory and Stopping the Server Creating Robust JMS Applications Using Basic Reliability Mechanisms Controlling Message Acknowledgment Specifying Message Persistence Setting Message Priority Levels Creating Temporary Destinations Using Advanced Reliability Mechanisms Creating Durable Subscriptions Using JMS API Local Transactions Using the JMS API in a Java EE Application Using@Resource Annotations in Java EE Components Using Session Beans to Produce and to Synchronously Receive Messages Using Message-Driven Beans to Receive Messages Asynchronously Managing Distributed Transactions Using the JMS API with Application Clients and Web Components 32. Java EE Examples Using the JMS API 36. The Coffee Break Application | The JMS API Programming ModelThe basic building blocks of a JMS application consist of
Figure 31-5 shows how all these objects fit together in a JMS client application. Figure 31-5 The JMS API Programming Model ![]() This section describes all these objects briefly and provides sample commands and codesnippets that show how to create and use the objects. The last subsectionbriefly describes JMS API exception handling. Examples that show how to combine all these objects in applications appear inlater sections. For more details, see the JMS API documentation, which is partof the Java EE API documentation. JMS Administered ObjectsTwo parts of a JMS application, destinations and connection factories, are best maintainedadministratively rather than programmatically. The technology underlying these objects is likely to bevery different from one implementation of the JMS API to another. Therefore, themanagement of these objects belongs with other administrative tasks that vary from providerto provider. JMS clients access these objects through interfaces that are portable, so a clientapplication can run with little or no change on more than one implementationof the JMS API. Ordinarily, an administrator configures administered objects in a JNDInamespace, and JMS clients then access them by using resource injection. With Sun Java System Application Server, you use theasadmin command or theAdmin Console to create JMS administered objects in the form of resources. JMS Connection FactoriesAconnection factory is the object a client uses to create a connection toa provider. A connection factory encapsulates a set of connection configuration parameters thathas been defined by an administrator. Each connection factory is an instance oftheConnectionFactory,QueueConnectionFactory, orTopicConnectionFactory interface. To learn how to create connection factories,seeCreating JMS Administered Objects for the Synchronous Receive Example. At the beginning of a JMS client program, you usually inject a connectionfactory resource into aConnectionFactory object. For example, the following code fragment specifies aresource whose JNDI name isjms/ConnectionFactory and assigns it to aConnectionFactoryobject: @Resource(mappedName="jms/ConnectionFactory")private static ConnectionFactory connectionFactory; In a Java EE application, JMS administered objects are normally placed in thejms naming subcontext. Note -ThemappedName element of the@Resource annotation is specific to the Application Server. JMS DestinationsAdestination is the object a client uses to specify the target ofmessages it produces and the source of messages it consumes. In the PTPmessaging domain, destinations are called queues. In the pub/sub messaging domain, destinations arecalled topics. A JMS application can use multiple queues or topics (or both).To learn how to create destination resources, seeCreating JMS Administered Objects for the Synchronous Receive Example. To create a destination using the Application Server, you create a JMSdestination resource that specifies a JNDI name for the destination. In the Application Server implementation of JMS, each destination resource refers to aphysical destination. You can create a physical destination explicitly, but if you donot, the Application Server creates it when it is needed and deletes itwhen you delete the destination resource. In addition to injecting a connection factory resource into a client program, youusually inject a destination resource. Unlike connection factories, destinations are specific to onedomain or the other. To create an application that allows you to usethe same code for both topics and queues, you assign the destination toaDestination object. The following code specifies two resources, a queue and a topic. The resourcenames are mapped to destinations created in the JNDI namespace. @Resource(mappedName="jms/Queue")private static Queue queue;@Resource(mappedName="jms/Topic")private static Topic topic; With the common interfaces, you can mix or match connection factories and destinations.That is, in addition to using theConnectionFactory interface, you can inject aQueueConnectionFactory resource and use it with aTopic, and you can inject aTopicConnectionFactory resource and use it with aQueue. The behavior of the applicationwill depend on the kind of destination you use and not on thekind of connection factory you use. JMS ConnectionsAconnection encapsulates a virtual connection with a JMS provider. A connection couldrepresent an open TCP/IP socket between a client and a provider service daemon.You use a connection to create one or more sessions. Connections implement theConnection interface. When you have aConnectionFactory object, you canuse it to create aConnection: Connection connection = connectionFactory.createConnection(); Before an application completes, you must close any connections that you have created.Failure to close a connection can cause resources not to be released bythe JMS provider. Closing a connection also closes its sessions and their messageproducers and message consumers. connection.close(); Before your application can consume messages, you must call the connection’sstartmethod; for details, seeJMS Message Consumers. If you want to stop message deliverytemporarily without closing the connection, you call thestop method. JMS SessionsAsession is a single-threaded context for producing and consuming messages. You usesessions to create the following:
Sessions serialize the execution of message listeners; for details, seeJMS Message Listeners. A session provides a transactional context with which to group a set ofsends and receives into an atomic unit of work. For details, seeUsing JMS API Local Transactions. Sessions implement theSession interface. After you create aConnection object, you useit to create aSession: Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); The first argument means that the session is not transacted; the second meansthat the session automatically acknowledges messages when they have been received successfully. (Formore information, seeControlling Message Acknowledgment.) To create a transacted session, use the following code: Session session = connection.createSession(true, 0); Here, the first argument means that the session is transacted; the second indicatesthat message acknowledgment is not specified for transacted sessions. For more information ontransactions, seeUsing JMS API Local Transactions. For information about the way JMS transactions work in JavaEE applications, seeUsing the JMS API in a Java EE Application. JMS Message ProducersAmessage producer is an object that is created by a session and usedfor sending messages to a destination. It implements theMessageProducer interface. You use aSession to create aMessageProducer for a destination. The followingexamples show that you can create a producer for aDestination object, aQueue object, or aTopic object: MessageProducer producer = session.createProducer(dest);MessageProducer producer = session.createProducer(queue);MessageProducer producer = session.createProducer(topic); You can create an unidentified producer by specifyingnull as the argument tocreateProducer. With an unidentified producer, you do not specify a destination until yousend a message. After you have created a message producer, you can use it tosend messages by using thesend method: producer.send(message); You must first create the messages; seeJMS Messages. If you created an unidentified producer, use an overloadedsend method that specifiesthe destination as the first parameter. For example: MessageProducer anon_prod = session.createProducer(null);anon_prod.send(dest, message); JMS Message ConsumersAmessage consumer is an object that is created by a session and usedfor receiving messages sent to a destination. It implements theMessageConsumer interface. A message consumer allows a JMS client to register interest in adestination with a JMS provider. The JMS provider manages the delivery of messagesfrom a destination to the registered consumers of the destination. For example, you could use aSession to create aMessageConsumer foraDestination object, aQueue object, or aTopic object: MessageConsumer consumer = session.createConsumer(dest);MessageConsumer consumer = session.createConsumer(queue);MessageConsumer consumer = session.createConsumer(topic); You use theSession.createDurableSubscriber method to create a durable topic subscriber. This methodis valid only if you are using a topic. For details, seeCreating Durable Subscriptions. After you have created a message consumer, it becomes active, and you canuse it to receive messages. You can use theclose method for aMessageConsumer to make the message consumer inactive. Message delivery does not begin untilyou start the connection you created by calling itsstart method. (Remember alwaysto call thestart method; forgetting to start the connection is oneof the most common JMS programming errors.) You use thereceive method to consume a message synchronously. You can usethis method at any time after you call thestart method: connection.start();Message m = consumer.receive();connection.start();Message m = consumer.receive(1000); // time out after a second To consume a message asynchronously, you use a message listener, described in thenext section. JMS Message ListenersAmessage listener is an object that acts as an asynchronous event handler formessages. This object implements theMessageListener interface, which contains one method,onMessage. IntheonMessage method, you define the actions to be taken when a messagearrives. You register the message listener with a specificMessageConsumer by using thesetMessageListenermethod. For example, if you define a class namedListener that implements theMessageListener interface, you can register the message listener as follows: Listener myListener = new Listener();consumer.setMessageListener(myListener); After you register the message listener, you call thestart method on theConnection to begin message delivery. (If you callstart before you registerthe message listener, you are likely to miss messages.) When message delivery begins, the JMS provider automatically calls the message listener’sonMessagemethod whenever a message is delivered. TheonMessage method takes one argument of typeMessage, which your implementation of the method can cast to any of theother message types (seeMessage Bodies). A message listener is not specific to a particular destination type. The samelistener can obtain messages from either a queue or a topic, depending onthe type of destination for which the message consumer was created. Amessage listener does, however, usually expect a specific message type and format. YouronMessage method should handle all exceptions. It must not throw checked exceptions,and throwing aRuntimeException is considered a programming error. The session used to create the message consumer serializes the execution of allmessage listeners registered with the session. At any time, only one of thesession’s message listeners is running. In the Java EE platform, a message-driven bean is a special kindof message listener. For details, seeUsing Message-Driven Beans to Receive Messages Asynchronously. JMS Message SelectorsIf your messaging application needs to filter the messages it receives, you canuse a JMS API message selector, which allows a message consumer to specifythe messages it is interested in. Message selectors assign the work of filteringmessages to the JMS provider rather than to the application. For an exampleof an application that uses a message selector, seeA Java EE Application That Uses the JMS API with a Session Bean. A message selector is aString that contains an expression. The syntax ofthe expression is based on a subset of the SQL92 conditional expression syntax.The message selector in the example selects any message that has aNewsTypeproperty that is set to the value'Sports' or'Opinion': NewsType = ’Sports’ OR NewsType = ’Opinion’ ThecreateConsumer,createDurableSubscriber methods allow you to specify a message selector as anargument when you create a message consumer. The message consumer then receives only messages whose headers and properties match theselector. (SeeMessage Headers, andMessage Properties.) A message selector cannot select messages on thebasis of the content of the message body. JMS MessagesThe ultimate purpose of a JMS application is to produce and toconsume messages that can then be used by other software applications. JMS messages havea basic format that is simple but highly flexible, allowing you tocreate messages that match formats used by non-JMS applications on heterogeneous platforms. A JMS message has three parts: a header, properties, and a body.Only the header is required. The following sections describe these parts: For complete documentation of message headers, properties, and bodies, see the documentation oftheMessage interface in the API documentation. Message HeadersA JMS message header contains a number of predefined fields that contain valuesthat both clients and providers use to identify and to route messages.Table 31-1 lists the JMS message header fields and indicates how their values areset. For example, every message has a unique identifier, which is represented inthe header fieldJMSMessageID. The value of another header field,JMSDestination, represents thequeue or the topic to which the message is sent. Other fields includea timestamp and a priority level. Each header field has associated setter and getter methods, which are documented inthe description of theMessage interface. Some header fields are intended to beset by a client, but many are set automatically by thesend orthepublish method, which overrides any client-set values. Table 31-1 How JMS Message Header Field Values Are Set
Message PropertiesYou can create and set properties for messages if you need valuesin addition to those provided by the header fields. You can use propertiesto provide compatibility with other messaging systems, or you can use them to createmessage selectors (seeJMS Message Selectors). For an example of setting a property to beused as a message selector, seeA Java EE Application That Uses the JMS API with a Session Bean. The JMS API provides some predefined property names that a provider can support.The use either of these predefined properties or of user-defined properties is optional. Message BodiesThe JMS API defines five message body formats, also called message types, whichallow you to send and to receive data in many different formsand provide compatibility with existing messaging formats.Table 31-2 describes these message types. Table 31-2 JMS Message Types
The JMS API provides methods for creating messages of each type and forfilling in their contents. For example, to create and send aTextMessage,you might use the following statements: TextMessage message = session.createTextMessage();message.setText(msg_text); // msg_text is a Stringproducer.send(message); At the consuming end, a message arrives as a genericMessage object andmust be cast to the appropriate message type. You can use oneor more getter methods to extract the message contents. The following code fragment usesthegetText method: Message m = consumer.receive();if (m instanceof TextMessage) { TextMessage message = (TextMessage) m; System.out.println("Reading message: " + message.getText());} else { // Handle error}JMS Queue BrowsersYou can create aQueueBrowser object to inspect the messages in a queue.Messages sent to a queue remain in the queue until the message consumerfor that queue consumes them. Therefore, the JMS API provides an object thatallows you to browse the messages in the queue and display the headervalues for each message. To create aQueueBrowser object, use theSession.createBrowser method.For example: QueueBrowser browser = session.createBrowser(queue); SeeA Simple Example of Browsing Messages in a Queue for an example of the use of aQueueBrowser object. ThecreateBrowser method allows you to specify a message selector as a secondargument when you create aQueueBrowser. For information on message selectors, seeJMS Message Selectors. The JMS API provides no mechanism for browsing a topic. Messages usually disappearfrom a topic as soon as they appear: if there are nomessage consumers to consume them, the JMS provider removes them. Although durable subscriptions allowmessages to remain on a topic while the message consumer is notactive, no facility exists for examining them. JMS Exception HandlingThe root class for exceptions thrown by JMS API methods isJMSException.CatchingJMSException provides a generic way of handling all exceptions related to theJMS API. TheJMSException class includes the following subclasses, which are described in the APIdocumentation:
All the examples in the tutorial catch and handleJMSException when it isappropriate to do so. Copyright © 2010, Oracle and/or its affiliates. All rights reserved.Legal Notices |