Saturday, June 24, 2006

Integrating JMS with EJB

JMS-EJB integration is a compelling idea. It would allow EJB components to benefit from the value proposition of messaging, such as non-blocking clients and multinary communications.

To understand the motivations behind introducing a completely different type of bean to consume messages in an EJB application, let us contemplate for a moment what other approaches could we have taken and whether they would have worked:

  • Using a Java object that receives JMS messages to call EJB components. Rather than coming up with a whole new type of bean, the Java community could have promoted the idea of a Java object that can receive messages and in turn call the appropriate EJB components, such as session beans and entity beans. The problems with this approach are as follows:

    • You'd need to write special code to register yourself as a listener for JMS messages. This is a decent amount of code (as we demonstrated previously).

    • To increase the throughput of message consumption, you would have to write the multithreading logic such that you can listen to the messages on multiple threads. However, writing multithreaded applications is not a trivial task for a business application developer.

    • Your Java object that listens to messages would need some way of starting up, since it wrapped your other EJB components. If the class ran within the container, you would need to use an EJB server-specific startup class to activate your Java object when the EJB server came up. This is not portable because EJB specification does not define a standard way of activating a given logic.

    • Your plain Java object wouldn't receive any services from an EJB container, such as automatic life cycle management, clustering, pooling, and transactions. You would need to hard-code this yourself, which is difficult and error-prone.

    • You would need to hard-code the JMS destination name in your Java object. This hurts reusability, because you couldn't reuse that Java object with other destinations. If you get the destination information from a disk (such as with property files), this is a bit clunky.

  • Reuse an existing type of EJB component somehow to receive JMS messages. Another option could have been to shoehorn session beans or entity beans into receiving JMS messages. Problems with this approach include:

    • Threading. If a message arrives for a bean while it's processing other requests, how can it take that message, given that EJB does not allow components to be multithreaded?

    • Life cycle management. If a JMS message arrives and there are no beans, how does the container know to create a bean

courtesy: Mastering EJB, Third Edition, Ed Roman

Single-Threaded versus Multithreaded Beans

One great benefit of EJB is you don't need to write thread-safe code. You design your enterprise beans as single-threaded components and never need to worry about thread synchronization when concurrent clients access your component. In order to service concurrent client requests, your EJB container automatically instantiates multiple instances of your component.

The container's thread services can be both a benefit and a restriction. The benefit is that you don't need to worry about race conditions or deadlock in your application code. The restriction is that some problems lend themselves well to multithreaded programming, and that class of problems cannot be easily solved in an EJB environment.

So why doesn't the EJB specification allow for multithreaded beans? EJB is intended to relieve the component developers' worry about threads or thread synchronization. The EJB container handles those issues for you by load-balancing client requests to multiple instances of a single-threaded component. An EJB server provides a highly scalable environment for single-threaded components.

If the EJB specification allowed for beans to control threads, a Pandora's box of problems would result. For example, an EJB container would have a very hard time controlling transactions if beans were randomly starting and stopping threads, especially because transaction information is often associated with a thread.

The bottom line is that EJB was not meant to be a Swiss army knife, solving every problem in existence. It was designed to assist with server-side business problems, which are largely single-threaded. For applications that absolutely must be multithreaded, EJB may not be the correct choice of distributed object architectures.

courtesy: Mastering EJB, Third Edition, Ed Roman

How Does Guaranteed Message Delivery Work?

With guaranteed message delivery, the MOM system persists your messages to a file, database, or other store. Your message resides in the persistent store until it's sent to a message consumer, and the message consumer acknowledges the consumption of the message. If the acknowledgment of a message is not received in a reasonable amount of time, the message remains on the persistent store and is redelivered.

This feature is beneficial when the message consumer is brought down on a regular basis for maintenance, and lost messages are unacceptable. This is especially true in industries, such as financial services, where messages represent securities changing hands.

A variation on the guaranteed message delivery theme is certified message delivery. Certified message delivery not only ensures the delivery of a message from a producer to a consumer, but also generates a consumption receipt that is delivered to the message originator, indicating a successful consumption of the message. Certified message delivery is used by producers to better manage communication with consumers.

Another variation of guaranteed message delivery is called store and forward. Store and forward enables a message producer to successfully send a message to an inactive MOM system. The producer transparently spools the message to a local store until the MOM system is reactivated, at which point the message is delivered to the MOM system and forwarded to any available consumers. Guaranteed message delivery without the store-and-forward option requires producers to send messages to active MOM systems, but consumers do not have to be active. Store and forward with guaranteed message delivery allows messages to be sent whether MOM systems or consumers are active or inactive.

courtesy : Mastering EJB, Third Edition, Ed Roman

Sunday, June 11, 2006

obtaining user transaction of the client from inside the bean

To control transactions from client code, you must look up the JTA UserTransaction interface with the Java Naming and Directory Interface (JNDI). JNDI is a generic lookup facility for looking up resources across a network, and it is fully described in Appendix A. The following code illustrates looking up the JTA UserTransaction interface from client code using JNDI:
/*
* 3: Look up the JTA UserTransaction interface
* via JNDI. The container is required to
* make the JTA available at the location
* java:comp/UserTransaction.
*/
userTran = (javax.transaction.UserTransaction)
ctx.lookup("java:comp/UserTransaction");

Wont this collide with any other usertransaction created by other client. How is the integrity assured?

beans vs allowed transactions

Here is a brief explanation of why certain transaction attributes are disallowed. Entity beans and stateful session beans with SessionSynchronization must use transactions. The reason is that both of these types of beans are inherently transactional in nature. Entity beans perform database updates, and stateful session beans with SessionSynchronization (which we describe later in this chapter) are also transactional. Therefore you normally can't use the following attributes: Never, NotSupported, Supports. Note that the EJB specification does allow for containers to optionally support these attributes for stateful session beans and entity beans—but only if you're using non-transactional data stores—and with the warning that if you use this, your beans will not be portable, and you may find that you receive inconsistent results.

A client does not call a message-driven bean directly; rather, message-driven beans read messages off a message queue in transactions separate from the client's transaction. There is no client, and therefore transaction attributes that deal with the notion of a client's transaction make no sense for message-driven beans—namely Never, Supports, RequiresNew, and Mandatory.

halting problem (a.k.a) infinite block problem

There is a huge caveat with using container-managed transactions with JMS message-driven beans in a certain scenario. Let's say you have an EJB component (any type of component) that sends and then receives a message all within one big container-managed transaction. In this case, the send operation will never get its message on the queue, because the transaction doesn't commit until after the receive operation ends. Thus, you'll be waiting for the receive operation to complete forever. This is called the infinite block problem, also known as the halting problem in computer science.

An easy solution to this problem is after sending the request message, you can call commit() on the JMS Session, which is your JMS transaction helper object. This causes the outgoing message buffer to be flushed. Hence, the receive operation does not have to wait forever for the transaction to commit to get a message.

[ref: Mastering EJB, Third Edition, Ed Roman et al.]

Friday, June 09, 2006

do applications always need an UI

Web Service clients. Some business applications require no user interface at all. They exist to interconnect with other business partners' applications that may provide their own user interface. For example, consider a scenario where Dell Computer Corporation needs to procure Intel chips to assemble and distribute desktop computers. Here, Intel could expose an Order Parts Web Service that enables the Dell Web Service client to order chips. In this case, the Intel system does not provide a graphical user interface per se, but rather it provides a Web Service interface.