This chapter looks at one of the principal types of component in the Java 2 Platform, Enterprise Edition (J2EE) — Enterprise JavaBeans (EJBs). See how EJBs are applied and how they are deployed. (This is chapter 4 from Sams Publishers, author Martin Bond, et. al., Teach Yourself J2EE in 21 Days, second edition, ISBN: 0-672-32558-6).
So far, you have been presented with a "black box" view of an EJB; it provides business functionality via an RMI remote interface, and it cooperates with its container to perform its duties. To understand, use, and ultimately write EJBs, you will need to know more in concrete terms about the Java programming artifacts that make up an EJB. In other words, what's in one?
There are four components to an EJB:
The remote interface—Defining the signatures of the business methods for the EJB
The home interface—Defining the signature of the methods associated with the bean lifecycle (creation, use and destruction)
The bean itself—A concrete Java class implementing the business and lifecycle method functionality
The deployment descriptor—Meta data about the EJB, such as component classes, EJB type, transaction demarcation, resource and EJB references, environment entries, and security requirements
The names of the two Java interfaces and the Bean class usually follow a simple convention. For a given remote interface XXX the home interface is called XXXHome and the bean implementation is XXXBean. (Some users prefer to use XXXEJB for the implementation class.) Although this convention is not enforced, it is recommended that you use it when naming your EJB components.
Similarly, as discussed later in the section "The Bean Implementation," there are corresponding rules about the names of methods defined in the interfaces and the names of methods in the bean implementation. Unlike the class names, these rules are part of the EJB specification and must be rigorously applied, otherwise your EJBs will not deploy correctly.
The Business Interface
As stated already, the primary purpose of an EJB is to deliver business or application logic. To this end, the bean developer will define or derive the business operations required of the bean and will formalize them in an RMI remote interface. This is referred to as the bean's remote (or business) interface as opposed to the home interface you will look at in a moment.
The actual methods defined on the remote interface will depend on the purpose of the bean, but there are certain general rules concerning the interface:
As with any RMI-based interface, each method must be declared as throwing java.rmi.RemoteException in addition to any business exceptions. This allows the RMI subsystem to signal network-related errors to the client.
RMI rules apply to parameters and return values, so any types used must either be primitives (int, boolean, float, and the like), or implement the Serializable or Remote interfaces. Most Java classes, such as String and the primitive wrapper classes, implement Serializable.
The interface must declare that it extends the javax.ejb.EJBObject interface.
Caution - Failure to conform to the rules about extending javax.ejb.EJBObject and throwing RemoteException will cause the interface to be rejected by tools that manipulate EJBs. Additionally, if you use parameter or return types that do not conform to the rules, your bean will compile and even deploy, but will fail with runtime errors.
The issue regarding object parameters and return values is worth considering for a moment. When you pass an object as a parameter into a local method call, a reference to the original object is used within the method. Any changes to the state of the object are seen by all users of that object because they are sharing the same object. Also, there is no need to create a copy of the object—only a reference is passed. This mechanism is known as pass by reference.
On the other hand, when using RMI remote methods, only objects that are serializable (that is, implement the Serializable interface) are passed. A copy of the object is made and this copy is passed over the remote interface to the method. This has several implications. First, users of a serializable object passed across a remote interface will no longer share the same object. Also, there may now be some performance costs associated with invoking a method through a bean's remote interface. Not only is there the cost of the network call, but also there is the cost of making a copy of the object so that it can be sent across the network. This mechanism is known as pass by value.
You can see an example of an EJB remote interface in Listing 4.1—in this case, the one for the Agency EJB used in the case study introduced on Day 2, "The J2EE Platform and Roles."
List select(String table) throws RemoteException; }
The remote interface lives in a package called agency, which will be common to all the classes that comprise the EJB. The definition imports java.rmi.* and javax.ejb.* for RemoteException and EJBObject, respectively. The rest of the interface is much as you would expect from any remote Java interface—in this case, passing Strings and returning serializable Collection objects.
Notice that all the methods must be declared as throwing RemoteException. This means that the client will have to handle potential exceptions that may arise from the underlying distribution mechanism. However, your application will probably want to utilize exceptions itself to indicate application-level errors. These exceptions should be declared as part of the remote interface, as shown by the use of NotFoundException and DuplicateException in the Agency interface.
This chapter is from Teach Yourself J2EE in 21 Days, second edition, by Martin Bond et. al. (Sams, 2004, ISBN: 0-672-32558-6). Check it out at your favorite bookstore today. Buy this book now.