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 | Using the JMS API in a Java EE ApplicationThis section describes the ways in which using the JMS API ina Java EE application differs from using it in a stand-alone client application:
A general rule in the Java EE platform specification applies to all JavaEE components that use the JMS API within EJB or web containers: Application components in the web and EJB containers must not attempt to createmore than one active (not closed)Session object per connection. This rule does not apply to application clients. Using@Resource Annotations in Java EE ComponentsWhen you use the@Resource annotation in an application client component, you normallydeclare the JMS resource static: @Resource(mappedName="jms/ConnectionFactory")private static ConnectionFactory connectionFactory;@Resource(mappedName="jms/Queue")private static Queue queue; However, when you use this annotation in a session bean, a message-driven bean,or a web component, donot declare the resource static: @Resource(mappedName="jms/ConnectionFactory")private ConnectionFactory connectionFactory;@Resource(mappedName="jms/Topic")private Topic topic; If you declare the resource static, runtime errors will result. Using Session Beans to Produce and to Synchronously Receive MessagesA Java EE application that produces messages or synchronously receives them can usea session bean to perform these operations. The example inA Java EE Application That Uses the JMS API with a Session Bean usesa stateless session bean to publish messages to a topic. Because a blocking synchronous receive ties up server resources, it is not agood programming practice to use such areceive call in an enterprise bean.Instead, use a timed synchronous receive, or use a message-driven bean to receivemessages asynchronously. For details about blocking and timed synchronous receives, seeWriting the Client Programs for the Synchronous Receive Example. Using the JMS API in a Java EE application is in manyways similar to using it in a stand-alone client. The main differences arein resource management and transactions. Resource ManagementThe JMS API resources are a JMS API connection and a JMSAPI session. In general, it is important to release JMS resources when theyare no longer being used. Here are some useful practices to follow.
TransactionsInstead of using local transactions, you use container-managed transactions for bean methods thatperform sends or receives, allowing the EJB container to handle transaction demarcation. Becausecontainer-managed transactions are the default, you do not have to use an annotationto specify them. You can use bean-managed transactions and thejavax.transaction.UserTransaction interface’s transaction demarcation methods,but you should do so only if your application has special requirements andyou are an expert in using transactions. Usually, container-managed transactions produce the most efficientand correct behavior. This tutorial does not provide any examples of bean-managed transactions. Using Message-Driven Beans to Receive Messages AsynchronouslyThe sectionsWhat Is a Message-Driven Bean? andHow Does the JMS API Work with the Java EE Platform? describe how the Java EE platform supports aspecial kind of enterprise bean, the message-driven bean, which allows Java EE applicationsto process JMS messages asynchronously. Session beans allow you to send messages andto receive them synchronously but not asynchronously. A message-driven bean is a message listener that can reliably consume messages froma queue or a durable subscription. The messages can be sent by anyJava EE component (from an application client, another enterprise bean, or a webcomponent) or from an application or a system that does not useJava EE technology. Like a message listener in a stand-alone JMS client, a message-driven bean containsanonMessage method that is called automatically when a message arrives. Like amessage listener, a message-driven bean class can implement helper methods invoked by theonMessage method to aid in message processing. A message-driven bean, however, differs from a stand-alone client’s message listener in thefollowing ways:
The EJB container automatically performs several setup tasks that a stand-alone client hasto do:
If JMS is integrated with the application server using a resource adapter, theJMS resource adapter handles these tasks for the EJB container. Your message-driven bean class must implement thejavax.jms.MessageListener interface and theonMessagemethod. It may implement a@PostConstruct callback method to create a connection, and a@PreDestroy callback method to close the connection. Typically, it implements these methods ifit produces messages or does synchronous receives from another destination. The bean class commonly injects aMessageDrivenContext resource, which provides some additional methodsthat you can use for transaction management. The main difference between a message-driven bean and a session bean is thata message-driven bean has no local or remote interface. Instead, it has onlya bean class. A message-driven bean is similar in some ways to a stateless session bean:Its instances are relatively short-lived and retain no state for a specific client.The instance variables of the message-driven bean instance can contain some state acrossthe handling of client messages: for example, a JMS API connection, an opendatabase connection, or an object reference to an enterprise bean object. Like a stateless session bean, a message-driven bean can have many interchangeable instancesrunning at the same time. The container can pool these instances to allowstreams of messages to be processed concurrently. The container attempts to deliver messagesin chronological order when it does not impair the concurrency of message processing,but no guarantees are made as to the exact order in which messagesare delivered to the instances of the message-driven bean class. Because concurrency canaffect the order in which messages are delivered, you should write your applicationsto handle messages that arrive out of sequence. For example, your application could manage conversations by using application-level sequence numbers. Anapplication-level conversation control mechanism with a persistent conversation state could cache later messagesuntil earlier messages have been processed. Another way to ensure order is to have each message or messagegroup in a conversation require a confirmation message that the sender blocks on receiptof. This forces the responsibility for order back on the sender and moretightly couples senders to the progress of message-driven beans. To create a new instance of a message-driven bean, the container does thefollowing:
To remove an instance of a message-driven bean, the container calls the@PreDestroycallback method. Figure 31-11 shows the life cycle of a message-driven bean. Figure 31-11 Life Cycle of a Message-Driven Bean ![]() Managing Distributed TransactionsJMS client applications use JMS API local transactions (described inUsing JMS API Local Transactions), whichallow the grouping of sends and receives within a specific JMS session. JavaEE applications commonly use distributed transactions to ensure the integrity of accesses to externalresources. For example, distributed transactions allow multiple applications to perform atomic updates onthe same database, and they allow a single application to perform atomic updateson multiple databases. In a Java EE application that uses the JMS API, you canuse transactions to combine message sends or receives with database updates and otherresource manager operations. You can access resources from multiple application components within a singletransaction. For example, a servlet can start a transaction, access multiple databases, invokean enterprise bean that sends a JMS message, invoke another enterprise bean thatmodifies an EIS system using the Connector architecture, and finally commit the transaction.Your application cannot, however, both send a JMS message and receive a replyto it within the same transaction; the restriction described inUsing JMS API Local Transactions still applies. Distributed transactions within the EJB container can be either of two kinds:
You can use either container-managed transactions or bean-managed transactions with message-driven beans. Toensure that all messages are received and handled within the context of atransaction, use container-managed transactions and use theRequired transaction attribute (the default) for theonMessage method. This means that if there is no transaction in progress, anew transaction will be started before the method is called and will becommitted when the method returns. When you use container-managed transactions, you can call the followingMessageDrivenContext methods:
If you use bean-managed transactions, the delivery of a message to theonMessage method takes place outside the distributed transaction context. The transaction begins whenyou call theUserTransaction.begin method within theonMessage method, and it ends whenyou callUserTransaction.commit orUserTransaction.rollback. Any call to theConnection.createSession method must take placewithin the transaction. If you callUserTransaction.rollback, the message is not redelivered, whereascallingsetRollbackOnly for container-managed transactions does cause a message to be redelivered. Neither the JMS API specification nor the Enterprise JavaBeans specification (available fromhttp://www.oracle.com/technetwork/java/index-jsp-140203.html) specifieshow to handle calls to JMS API methods outside transaction boundaries. The EnterpriseJavaBeans specification does state that the EJB container is responsible for acknowledging amessage that is successfully processed by theonMessage method of a message-driven beanthat uses bean-managed transactions. Using bean-managed transactions allows you to process the message byusing more than one transaction or to have some parts of the messageprocessing take place outside a transaction context. In most cases, however, container-managed transactionsprovide greater reliability and are therefore preferable. When you create a session in an enterprise bean, the container ignores thearguments you specify, because it manages all transactional properties for enterprise beans. Itis still a good idea to specify arguments oftrue and0to thecreateSession method to make this situation clear: session = connection.createSession(true, 0); When you use container-managed transactions, you normally use theRequired transaction attribute (the default)for your enterprise bean’s business methods. You do not specify a message acknowledgment mode when you create amessage-driven bean that uses container-managed transactions. The container acknowledges the message automatically when itcommits the transaction. If a message-driven bean uses bean-managed transactions, the message receipt cannot be partof the bean-managed transaction, so the container acknowledges the message outside the transaction. If theonMessage method throws aRuntimeException, the container does not acknowledgeprocessing the message. In that case, the JMS provider will redeliver the unacknowledgedmessage in the future. Using the JMS API with Application Clients and Web ComponentsAn application client in a Java EE application can use the JMSAPI in much the same way that a stand-alone client program does. Itcan produce messages, and it can consume messages by using either synchronous receivesor message listeners. SeeChapter 23, A Message-Driven Bean Example for an example of an application client thatproduces messages. For an example of using an application client to produce andto consume messages, seeAn Application Example That Deploys a Message-Driven Bean on Two Servers. The Java EE platform specification does not impose strict constraints on how webcomponents should use the JMS API. In the Application Server, a web componentcan send messages and consume them synchronously but cannot consume them asynchronously. Because a blocking synchronous receive ties up server resources, it is not agood programming practice to use such areceive call in a web component.Instead, use a timed synchronous receive. For details about blocking and timed synchronousreceives, seeWriting the Client Programs for the Synchronous Receive Example. Copyright © 2010, Oracle and/or its affiliates. All rights reserved.Legal Notices |