Enterprise Java Beans (EJBs) are intended to build business applications in a portable manner by moving environmental variations into EJB containers and servers, and leaving only the business logic to be written. EJBs occupy a different space to Jini services. Nevertheless, they may act in a complementary manner, by allowing remote Jini clients to dynamically locate EJB services. This chapter explores some of the issues in this.
Building business applications involves isolating and coding business logic. it may also involve a large number of environmental considerations, which are necessary to actually run the application, but are outside of this business logic. For example
Enterprise Java Beans are typically expected to run in an n-tier client-server model. The components of such a system are typically long-lived statically located services. This shows up in various ``hard-coded'' aspects of an EJB system, such as the location of a JNDI (Java Naming and Directory Interface) service.
Jini, on the other hand, allows a more dynamic view of a system. Services may start and stop arbitrarily, and may change location. An application can make use of whatever services happen to be available, and may be able to perform many functions even if services are missing. A Jini application can make use of many services to blend them together as needed. In contrast, an enterprise application will appear as a much more monolithic structure, even if it happens to be built from distributed components.
An EJB system will often be a distributed system. It will rely on JNDI to locate services and objects; it may use CORBA for communication; some objects will use RMI, but this may be either the standard RMI protocol or RMI over IIOP; it will use the CORBA Object Transaction Service. These will all be handled by the EJB servers and containers supplied by a vendor
An enterprise bean is intended to be focussed on business logic. It is not made public, but is instead encapsulated in an EJB container. It is not allowed to do certain things, since that would complicate it in ways intended to be reserved for the EJB servers and containers. For example, it must run in a single thread, because all thread management is left to its container. This alone is enough to disqualify it as a Jini service, because discovery, leasing and invocation are all multi-threaded in implementation. More fundamentally, though, an enterprise bean is supposed to encapsulate business logic, not how it interacts with clients and lookup services!
An excellent overview of the EJB architecture and components from the point of view of the developer is given in http://www.nova-labs.com/ . Those new to EJBs are recommended to read that article and to look at the ``Enterprise JavaBeans Tutorial'' on http://java.sun.com/ .
An EJB ``object'' consists of a number of different objects
Home
object, which is responsible for creation and removal of the
bean. This is automatically generated from an interface specification
given by the application programmer
EJBObject
, which acts as an RMI remote object visible to the client.
It is automically generated from an interface specification given by the
application programmer
The structure of an EJB application is given in figure 0.1
In order to build an EJB service, a number of interfaces and implementations must be given. For example, to make an EJB version of a FileClassifier means specialising the general EJB architecture diagram as in figure 0.2
The FileClassifier
interface for EJBs will act as the interface through
which clients access the service. In this, it is similar to interfaces for Jini.
Implementations of this interface will be Remote
objects, and this interface
will extend Remote
. This differs from Jini, where it is optional about
how interfaces are implemented. The interface will also extend the EJBObject
interface
package ejb;
/**
* FileClassifier.java
*/
import java.rmi.Remote;
import javax.ejb.*;
import common.MIMEType;
public interface FileClassifier extends EJBObject, Remote {
MIMEType getMIMEType(String fileName)
throws java.rmi.RemoteException;
} // FileClassifier
The EJB server vendor will supply tools to generate necessary code from this:
specifying the interface is all that needs to be done to this part of an EJB system.
The vendor tools will generate proxies (and skeletons if needed), using either standard
RMI, RMI over IIOP, or some other remote implementation.
The Home interface must also be given. This basically defines the methods create()
and, if needed, remove()
. The purpose of this interface is to define
what type of object is created (as an interface), and to specify any parameters to
creation. In a case such as this, the interface is almost vacuous but has to be given
anyway.
package ejb;
/**
* FileClassifierHome.java
*/
import javax.ejb.*;
import java.rmi.RemoteException;
public interface FileClassifierHome extends EJBHome {
public FileClassifier create() throws CreateException, RemoteException;
} // FileClassifierHome
The vendor implementation will again take care of generating any implementation code
needed for this interface.
The EJB bean needs a full implementation. The FileClassifierBean
is a very
simple bean, and will not utilise all of the capabilities of EJBs. EJBs can be saved
to secondary storage and restored from there. This bean will not have any state, so
nothing special needs to be done: the methods ejbPassivate()
and
ejbActivate()
can have empty implementations. Creation of this bean
does not require any work, so ejbCreate()
also has an empty implementation.
Similarly, removal of the bean is an empty operation. The only method that requires
a non-empty implementation is the ``business logic'' operation getMIMEType()
package ejb;
/**
* FileClassifierBean.java
*/
import javax.ejb.*;
import common.MIMEType;
public class FileClassifierBean implements SessionBean {
public FileClassifierBean() {
// empty constructor required by EJB 1.1
}
public void ejbCreate() {
// empty
}
public void ejbActivate() {
//empty
}
public void ejbPassivate() {
//empty
}
public void ejbRemove() {
// empty
}
public void setSessionContext(SessionContext ctx) {
// empty
}
public MIMEType getMIMEType(String fileName) {
if (fileName.endsWith(".gif")) {
return new MIMEType("image", "gif");
} else if (fileName.endsWith(".jpeg")) {
return new MIMEType("image", "jpeg");
} else if (fileName.endsWith(".mpg")) {
return new MIMEType("video", "mpeg");
} else
// fill in lots of other types,
// but eventually give up and
return null;
}
} // FileClassifierBean
There is a very important distinction to note here between service implementations using Jini and service implementations by Enterprise Java Beans. A Jini service implements the interface, and directly supplies service objects or proxies for that interface. An EJB does not implement the interface. The interface is used by the EJB vendor to generate suitable proxies and backend objects. The backend object will communicate with the service, but this is by a local method call, not by any inheritance or interface implementation mechanism. The EJB remote object and the bean are completely separate objects.
This will have implications when we come to turn the EJB service into a Jini service. The bean is designed to be a local object, with no knowledge of its environment. It certainly will not be involved in making (or receiving) remote calls to or from other objects. Anything along those lines will be mediated by the EJB vendor objects.
We have defined two interfaces and one class: FileClassifier
,
FileClassifierHome
and FileClassifierBean
.
They are linked, but not by any mechanisms
within the Java language (they do not even share an interface). The EJB vendor objects
need to be informed of these links, plus additional information that it can use to
form a suitable runtime environment for the EJB. This is done using a
deployment descriptor, which will end up being a serialised
form of a descriptor object. Typical information in a descriptor is
FileClassifier
ejb.FileClassifierBean
ejb.FileClassifierHome
ejb.FileClassifier
How the deployment descriptor is produced depends on the EJB vendor. It may be created using a GUI interface, or be generated out of text files. Delving into details of vendor methods is beyond the scope of this book. The Sun tutorial on EJBs describes what is involved for one vendor's system. Individual vendors will also have descriptions on this process.