|[ Team LiB ]|
So far, we've looked at the different types of EJBs as defined by the specification along with the list of services the EJB container offers. Now let's look at what constitutes an enterprise bean. An Enterprise JavaBean is not a single class. An enterprise bean consists of a set of Java files along with a set of XML files that contain the deployment descriptors describing the enterprise bean. For implementing a Session or Entity bean, the EJB developer has to define the component interfaces, the home interface, and a bean class. In the case of Entity beans, the EJB developer could also define a primary key class. Message-Driven beans are different from the Session and Entity bean types in that they require only the bean class and have no need for interfaces.
The Bean Class
All bean types' bean class implements specialized interfaces that extend from the javax.ejb.EnterpriseBean interface. Table 20.3 defines the base classes for the different bean types.
Figure 20.4 describes the class hierarchy for the bean classes listed in Table 20.2. The Session and Entity bean classes define the bean's business methods and also define the life cycle–related methods; for example, create, remove, and so on. The bean class should implement all the methods defined in the component interfaces. The bean class doesn't implement the home or component interfaces directly. The method signatures should match exactly with business methods defined in the home and component interfaces, and should have methods corresponding to non-business methods (for example, life cycle methods such as create, remove, and so forth) in all interfaces. This is because the EJB compiler generates the objects that actually implement the remote home and remote interfaces.
Because the container automatically invokes Message-Driven beans to process JMS requests, these beans implement only the bean class base interface. The home and component interfaces do not apply to Message-Driven beans. A Message-Driven bean implements javax.jms.MessageListener apart from javax.ejb.MessageDrivenBean. The MessageListener interface defines only one method, onMessage(), to handle the JMS requests. The container invokes this method automatically. In the future, the specification might address Message-Driven beans handling other kinds of messages.
The remote interface provides access to the bean's business methods to clients that use the bean. This interface extends from the javax.ejb.EJBObject interface, which in turn extends from the java.rmi.Remote interface for providing remote connectivity. Figure 20.5 describes the class hierarchy for the remote interface. It contains two sample beans: a Trader Session bean and an Account Entity bean. This interface works with the remote home interface of a bean to provide services to other applications.
Now let's examine the interface javax.ejb.EJBObject from which all bean types' remote interface are extended. This provides the functionality that enables us to use our remote interface over the network using RMI. Apart from this, the EJBObject interface provides the client with some very useful methods that describe the bean:
The home interface provides applications that want to use the bean access to the bean's life cycle methods. Figure 20.6 illustrates the class hierarchy of the home interface with two examples: TraderHome and AccountHome. Life cycle methods are those used to create new beans, remove existing ones, and find beans based on some criteria. The remote home interface is represented by the interface javax.ejb.EJBHome. The bean's remote home interface extends from this interface and provides access to appropriate methods. The EJBHome interface, in turn, extends from the java.rmi.Remote interface. This interface works along with the remote interface.
The remote home interface extends the EJBHome interface. This interface provides the remote access functionality to our remote home interface. Apart from this, the EJBHome interface also provides the client with some very useful methods that describe the bean.
As mentioned, the getEJBMetaData method returns an object of type EJBMetaData. This object contains some very important pieces of information that describe the bean. This information is useful for development tools while building applications that use deployed EJBs. Clients that use scripting languages to access the beans can also benefit from this information.
Table 20.4 lists the values returned by the two functions—namely, isStatelessSession and isSession—related to identifying bean types based on the available session.
Local and Local Home Interfaces
If the local home interface of the bean extends from the interface javax.ejb.EJBLocalHome instead of the javax.ejb.EJBHome interface, other beans residing within the same container can efficiently use the bean. This interface offers similar bean life cycle methods as those offered by the remote home interface. The difference between the two is that when beans are created using this interface, no network connectivity is involved because both the requested and the requestor exist within the same container. This drastically improves performance for such local access. This interface works in conjunction with the local home interface.
The local interface of a bean is similar to the remote interface in that this interface also provides access to the business methods provided by the bean class. This interface works with the local home interface to provide access to the bean instance for other beans within the same container. All method calls made using this interface avoid network protocols, and thus improve performance. The local interface of a bean extends the javax.ejb.EJBLocalObject interface.
The same bean may provide both local and remote access, or just any one of them, by including the appropriate set of home and object interfaces in its deployment descriptor. There is a downside to using local interfaces: It reduces the location transparency of the beans. So, if you're sure that the objects will always colocate, give preference to using local interfaces.
Remote access involves passing parameters by value (copying), whereas local access involves passing them by reference (sharing). If a bean tries to modify its parameters and you switch its access from local to remote (or vice versa), the results are unpredictable. To avoid being trapped, do not modify parameters.
The local component interfaces have been optimized in such a way that any call made using a local interface is made as if it were just another call to any other object on the JVM. This means that with local interfaces, there is no requirement for the parameter objects to be serializable and they are passed by reference to the bean.
The local interface provides similar methods as the remote interface. There are a couple of differences between these two interfaces. All other methods provided by the EJBObject interface are also provided by the EJBLocalObject interface and behave in exactly the same way. We'll list only the differences between the two interfaces here.
The EJBLocalHome interface, unlike the EJBHome interface, has just a single remove method that takes a primary key as its parameter. Needless to say, this method cannot be invoked for Session beans. If it is, the method throws a RemoveException.
This is a special class that pertains only to Entity bean implementations. It provides an identifier for the database record that the Entity bean represents. This class has to implement java.io.Serializable. This class will be used in the finder method (findByPrimaryKey() method) of the home interface to locate the specific entity. This is covered in detail in the chapter on Entity beans (see Chapter 22, "Working with Entity Beans").
Because EJBs conform to RMI-IIOP standard, all methods in the remote EJB object and remote home interface have to throw remote exceptions (java.rmi.RemoteException). Remote exceptions indicate a network failure or other fatal situations. But the local interfaces and local home are different from the remote counter parts in that they don't throw remote exceptions at all. This is quite obvious because no network functionality is involved when using local interfaces.
EJB separates system-level exceptions from application exceptions. A system-level exception might include fatal situations such as a database failure, a server crash, and so on. The generated implementation classes might handle these errors and provide transparent failover in some cases (such as a server crash) by moving to another bean deployed in the clustered server. All application exceptions are always thrown back to the client. The application exceptions include bean-defined exceptions such as FinderException and CreateException as well as business exceptions.
EJB Naming Conventions
Let's establish some naming conventions to provide clarity for our discussion of EJBs in the next three chapters. We look at these conventions with the help of one of the real-world examples: an airline reservation system that we use as a business case to explain the session beans in the next chapter. Although we speak about an EJB as a whole, we'll refer to it using its business name with the suffix EJB. For example, AirlineReservationEJB and AirlineReservation EJB. This identifies the EJB as a whole and not the bean class alone. That is, you won't find a file called AirlineReservationEJB.java. Instead that name refers to a set of .java files. Similarly, when we refer to a Session bean, or just a bean, we're referring to the bean as a whole, which includes all constituents as listed in the previous sections. This goes for Entity beans and Message-Driven beans.
When naming a Bean class, we'll use its business name with the suffix Bean; for example, AirlineReservationBean. We'll also distinguish between the different types of interfaces by using appropriate suffixes. A remote home interface will be referred to using the business name of the bean along with the suffix RemoteHome. For example, the remote home interface for the AirlineReservation EJB is called AirlineReservationRemoteHome. On the other hand, a local home interface will hold the suffix LocalHome to distinguish it from the remote counterpart (for example, AirlineReservationLocalHome). A remote interface will be denoted with the business name and the suffix RemoteObject, whereas its local object counterpart will have the suffix Local appended to the business name. For example, AirlineReservationRemoteObject denotes a remote interface for the AirlineReservation EJB, whereas AirlineReservationLocalObject denotes its local interface.
Note also that when we refer to a client in our discussion, we aren't necessarily referring to a user interface unless it is explicitly specified. We're referring to any object that uses the EJB—the client to the bean.
|[ Team LiB ]|