Session Bean Client Interfaces
Now that we have seen how to build session bean components on the server side, let's explore how clients can tap the services provided by these components. Two main types of interfaces exist for client interfacing to a session bean: a session bean home interface and a session bean remote interface. The session bean home interface is used primarily as a factory to create references to session bean objects. The session bean remote interface then provides the client-side interface to the distributed session bean object's application-specific operations. Additionally, both home and remote interfaces provide a means to destroy client object references.
Session Bean Remote Interfaces
A session bean remote interface defines the set of application-specific distributed operations that can be invoked on a particular session bean. Remote interfaces describe the client's view of the EJB akin to the way RMI remote interfaces describe the client's view of an RMI server. In fact, remote interfaces are essentially defined using RMI semantics and can be used with RMI/JRMP and RMI/IIOP. A CORBA mapping to such interfaces also exists.
Session Bean Remote Interface Logical Architecture
Figure 3 depicts the basic logical architecture for building and using remote EJB client interfaces to distributed session EJBs.
Figure 3 The session bean remote interface architecture.
All application-specific interfaces to distributed EJB objects, such as MySessionEJB, shown in the figure, must extend the javax.ejb.EJBObject interface. EJBObject, in turn, extends java.rmi.Remote, which adds the distributed RMI semantics to remote EJB interfaces. Under the hood, remote interfaces make use of some container-provided stub implementation on the client side that handles the marshaling of calls to the distributed server-side skeleton. Skeletons then delegate calls to the actual server-side EJB component implementation, such as the MySessionEJBean shown in the figure. Runtime EJB containers are ultimately responsible for managing which bean instance is used and how calls are routed on the server side, but the result is that calls from an EJB client to application-specific EJB remote interface methods ultimately result in the invocation of an associated application-specific method on the server-side EJB component instance.
An application-specific remote EJB interface must be created for each EJB component. This interface provides the distributed interface usable by EJB clients to invoke the application-specific logic of EJB components. For each distributable application-specific method on an EJB server-side component, such as MySessionEJBean.someMethod(), an associated application-specific method must be defined on the EJB client-side remote interface, such as MySessionEJB.someMethod(). As a side effect of their distributable nature, each method in the application-specific remote interface should also declare that it can throw a java.rmi.RemoteException. In addition to application-specific interfaces on an EJB remote interface, a set of methods inherited from EJBObject can be invoked on a remote EJB object.
Session Bean Home Interfaces
Session bean clients use home interfaces to create initial references to session beans as well as to remove these references. These references, of course, are implemented via the remote session bean interface objects. Clients should always use home interfaces to create references to EJBs because these provide the container with the opportunity it needs to manage how to allocate EJB bean instance resources. Furthermore, if a client bypasses home interfaces and uses an EJBObject handle retrieved by some other means, such as via a JNDI lookup, it runs the risk of causing a threading problem. Again, this is because no more than one client thread can utilize a single server-side bean instance.
Session Bean Home Interface Logical Architecture
Figure 4 depicts the architecture behind creating session bean home interfaces and shows how clients may use these interfaces. JNDI is used to obtain handles to application-specific EJB home interface objects, such as MySessionEJBHome, which must extend the standard javax.ejb.EJBHome interface. Application-specific EJB home interface objects are also implemented on the client side by stubs, which communicate with server-side skeletons, and the container, which creates, destroys, and delegates calls to session bean instances as appropriate. Home interfaces can also be used for persisting their handles for later reconstruction and for obtaining metadata about the EJBs that they serve to create.
Figure 4 The session bean home interface architecture.
An EJB client must first obtain a handle to an EJB's home interface when it wants to create a new reference to the EJB. This task is accomplished via JNDI. Clients that operate inside a J2EE container environment can utilize the default parameterless constructor of the InitialContext object and simply look up a handle to an EJB's home interface with a call to InitialContext.lookup(). The J2EE container handles establishing the system properties that should be assumed by the InitialContext object. The name passed to an InitialContext.lookup() can refer to an <ejb-ref> element in the client's XML-based deployment descriptor. The <ejb-ref> element defines the reference name that will be used in creating the name passed to InitialContext.lookup(), the type of EJB being referenced, the home information, the remote information, and the linking information, as illustrated in Listing 1.
Listing 1 EJB Reference Example
<ejb-jar> ... <enterprise-beans> <session> ... <ejb-ref> <ejb-ref-name>ejb/tshirt</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>ejava.ejbch36.tshirt.TShirtHome</home> <remote>ejava.ejbch36.tshirt.TShirt</remote> </ejb-ref> ... </session> </enterprise-beans> ... </ejb-jar>
A series of one or more create(...) methods is defined on the custom home interface to represent the different ways in which the associated EJB can be created. A single create(...) method must be defined on the home interface for each ejbCreate(...) method defined on the EJB implementation. Each version of a create(...) method returns an instance of the EJB's remote interface (for example, MySessionEJB) and contains zero or more input parameters related to the specific types of initialization parameters needed by the associated ejbCreate(...) methods. Each create(...) method must also be defined to throw a java.rmi.RemoteException and javax.ejb.CreateException. Additionally, each create(...) method must be defined to throw any application-specific exceptions that have been defined for its associated ejbCreate(...) method.
Because stateless session beans define only one parameterless ejbCreate() method, stateless session bean home interfaces can define only one parameterless create() method. Invoking create() on stateless session beans only induces a container to pull a bean instance from the pool and does not necessarily cause the container to call ejbCreate() on the bean at that moment. However, stateful session beans do induce the container to call ejbCreate(...) on a bean instance with any parameters passed into an associated home interface create(...) method.