ne of the most common complaints about EJB architectures is that they are too resource-intensive, both in terms of memory consumption and response time. Memory consumption is directly related to the container provider and the architectural decisions made for the system. The EJB 2.0 spec doesn’t address such issues. It does, however, provide a means of reducing the response time for a request that involves interaction between multiple beans within the same container.
The 1.0 and 1.1 specifications defined only one way to reference one enterprise bean from another?through the bean’s remote interface. If both beans are in the same container, then this network round-trip is unnecessary. The 2.0 specification defines a new type of enterprise bean reference to avoid this problem?the local reference.
How can I reduce the unnecessary cost imposed when referencing one enterprise bean from another enterprise bean located in the same container?
Use EJB 2.0 Local References.
Overview:
Two Kinds of References
To access enterprise beans from other enterprise beans, a special mechanism is provided by the container. This mechanism allows a bean provider to refer to the homes of other enterprise beans using “logical” names called EJB references. These references are special entries declared in the application’s deployment descriptor that is then used by the container to construct the enterprise bean’s environment. In the deployment descriptor, the Deployer binds the EJB references used in the enterprise bean code to the homes of other enterprise beans that the bean needs to access.
Before the EJB 2.0 Specification, there was only one way to reference one enterprise bean from another. That was to use the bean’s remote interface, which requires a remote procedure call across the network, just like a normal EJB client. If several beans are collaborating to fill a particular transaction, then the expense of marshalling and unmarshalling the necessary objects across the network can become quite substantial.
With the 2.0 Specification, a new kind of bean interface was defined that would allow beans in the same container to refer to each other directly, without the network overhead of the remote interface. This new mechanism is called a local interface. A local interface is a standard Java interface that does not inherit from RMI. An enterprise bean can be defined as having a local interface, a remote interface, or both.
Specifying a Local Reference for a Bean
A local reference is specified in the same manner that a traditional remote reference is specified – the deployment descriptor. In fact, the deployment descriptor elements for a local reference mirror exactly the elements for a remote reference.
The code snippet below is a look at a typical remote reference:
This is a Product entity ejb/Product Entity com.xyz.widgets.ProductHome com.xyz.widgets.Product ../products/product.jar#Product
The code snippet below is a look at a local reference for the same bean:
This is a Product entity ejb/Product Entity com.xyz.widgets.ProductHome com.xyz.widgets.Product ../products/product.jar#Product
Here’s a quick look at what each of these elements is used for:
The top-level, containing element | |
An optional element used to provide a comments | |
The logical name used with the referencing beans code to refer to this reference | |
The Java type expected by the enterprise bean | |
The fully qualified class name for the referenced beans local home interface | |
The fully qualified class name for the referenced beans local interface | |
An optional element that can be used to create a greater degree of decoupling between the two enterprise beans |
Creating a Local Interface and Accessing a Bean Through It
In order to change an existing remote reference into a local reference, three things must be changed ?the deployment descriptor, the bean’s interfaces, and the actual call to the other enterprise bean. In the previous section you learned how to specify a local reference via the deployment descriptor. Now you need to convert the remote interfaces into local interfaces and then modify the actual JNDI lookup call to use the new local interfaces.
The Home Interface
To specify a home interface, you must import “javax.ejb.EJBLocalHome” rather than “javax.ejb.EJBHome”. The interface declaration must also be modified so that it inherits from “EJBLocalHome” (a standard Java interface), rather than “EJBHome” (an RMI interface). Also, the only exception that must be thrown by methods declared in this interface is:
javax.ejb.CreateException as java.rmi.RemoteException is no longer needed.
The Local Interface
To specify a local interface, you must import “javax.ejb.EJBLocalObject” rather than “javax.ejb.EJBObject”. The interface declaration must also be modified so that it inherits from “EJBLocalObject” (a standard Java interface), rather than “EJBObject” (an RMI interface).
Making the Call
Once the interfaces have been created and the deployment descriptor settings specified, all that remains is to perform the actual JNDI call to lookup the reference to the other enterprise bean. When making a call to a bean’s remote interface, the javax.rmi.PortableRemoteObject’s “narrow()” method is used to marshal the call via RMI. With a local reference, this overhead is not necessary. Instead, a simple JNDI lookup and appropriate typecast is required. The following code provides an example:
home = (ProductHome) initCtx.lookup(“java:comp/env/ejb/Product”);
Not only is this more efficient, but it is also much cleaner looking than the method used for obtaining a remote reference
The local interface provides a more efficient means of communicating between two enterprise beans that reside within the same container. This technique is especially useful when working with entity beans, as it is a well-established practice to access entity beans through session beans, rather than the client accessing the entity beans directly.
If you want to begin to use local references in your own code, be sure and check with your vendor (BEA, IBM, Borland, Silverstream, etc.) to determine if the application server version your are working is able to support local references. It will still take some time before the 2.0 spec is adopted across the board.