Suppose[95] you need to develop a multi-tiered application to view and update records in a database through a Web interface. You can write a database application using JDBC, a Web interface using JSP/servlets, and a distributed system using CORBA/RMI. But what extra considerations must you make when developing a distributed object system rather than just knowing APIs? Here are the issues: Comment
Performance: The distributed objects you create must perform well, as they could potentially service many clients at a time. Youll need to use optimization techniques such as caching as well as pooling resources like database connections. Youll also have to manage the lifecycle of your distributed objects. Comment
Scalability: The distributed objects must also be scalable. Scalability in a distributed application means that the number of instances of your distributed objects can be increased and moved onto additional machines without modifying any code. Comment
Security: A distributed object must often manage the authorization of the clients that access it. Ideally, you can add new users and roles to it without recompilation. Comment
Distributed Transactions: A distributed object should be able to reference distributed transactions transparently. For example, if you are working with two separated databases, you should be able to update them simultaneously within the same transaction and roll them both back if a certain criteria is not met. Comment
Reusability: The ideal distributed object can be effortlessly moved onto another vendors application server. It would be nice if you could resell a distributed object component without making special modifications, or buy someone elses component and use it without having to recompile or rewrite it. Comment
Availability: If one of the machines in the system goes down, clients should automatically fail-over to backup copies of the objects running on other machines. Comment
These considerations, in addition the business problem that you set out to solve, can make for a daunting development project. However, all the issues except for your business problem are redundantsolutions must be reinvented for every distributed business application. Comment
Sun, along with other leading distributed object vendors, realized that sooner or later every development team would be reinventing these particular solutions, so they created the Enterprise JavaBeans specification (EJB). EJB describes a server-side component model that tackles all of the considerations mentioned above using a standard approach that allows developers to create business components called EJBs that are isolated from low-level plumbing code and that focus solely on providing business logic. Because EJBs are defined in a standard way, they can vendor independent. Comment
Because of the similarity in names, there is much confusion about the relationship between the JavaBeans component model and the Enterprise JavaBeans specification. While both the JavaBeans and Enterprise JavaBeans specifications share the same objectives in promoting reuse and portability of Java code between development and deployment tools with the use of standard design patterns, the motives behind each specification are geared to solve different problems. Comment
The standards defined in the JavaBeans component model are designed for creating reusable components that are typically used in IDE development tools and are commonly, although not exclusively, visual components. Comment
The Enterprise JavaBeans specification defines a component model for developing server side java code. Because EJBs can potentially run on many different server-side platformsincluding mainframes that do not have visual displaysAn EJB cannot make use of graphical libraries such as AWT or Swing. Comment
The Enterprise JavaBeans specification describes a server-side component model. It defines six roles that are used to perform the tasks in development and deployment as well as defining the components of the system. These roles are used in the development, deployment and running of a distributed system. Vendors, administrators and developers play the various roles, to allow the partitioning of technical and domain knowledge. The vendor provides a technically sound framework and the developers create domain-specific components; for example, an accounting component. The same party can perform one or many roles. The roles defined in the EJB specification are summarized in the following table:Comment
Role |
Responsibility |
Enterprise Bean Provider |
The developer responsible for creating reusable EJB components. These components are packaged into a special jar file (ejb-jar file). |
Application Assembler |
Creates and assembles applications from a collection of ejb-jar files. This includes writing applications that utilize the collection of EJBs (e.g., servlets, JSP, Swing etc. etc.). |
Deployer |
Takes the collection of ejb-jar files from the Assembler and/or Bean Provider and deploys them into a run-time environment: one or more EJB Containers. |
EJB Container/Server Provider |
Provides a run-time environment and tools that are used to deploy, administer, and run EJB components. |
System Administrator |
Manages the different components and services so that they are configured and they interact correctly, as well as ensuring that the system is up and running. |
EJB components are elements of reusable business logic that adhere to strict standards and design patterns as defined in the EJB specification. This allows the components to be portable. It also allows other servicessuch as security, caching and distributed transactionsto be performed on behalf of the components. An Enterprise Bean Provider is responsible for developing EJB components. Comment
The EJB Container is a run-time environment that contains and runs EJB components and provides a set of standard services to those components. The EJB Containers responsibilities are tightly defined by the specification to allow for vendor neutrality. The EJB container provides the low-level plumbing of EJB, including distributed transactions, security, lifecycle management of beans, caching, threading and session management. The EJB Container Provider is responsible for providing an EJB Container. Comment
An EJB Server is defined as an Application Server that contains and runs one or more EJB Containers. The EJB Server Provider is responsible for providing an EJB Server. You can generally assume that the EJB Container and EJB Server are the same. Comment
Java Naming and Directory Interface (JNDI) is used in Enterprise JavaBeans as the naming service for EJB Components on the network and other container services such as transactions. JNDI maps very closely to other naming and directory standards such as CORBA CosNaming and can actually be implemeted as a wrapper on top of it. Comment
JTA/JTS is used in Enterprise JavaBeans as the transactional API. An Enterprise Bean Provider can use the JTS to create transaction code, although the EJB Container commonly implements transactions in EJB on the EJB components behalf. The deployer can define the transactional attributes of an EJB component at deployment time. The EJB Container is responsible for handling the transaction whether it is local or distributed. The JTS specification is the Java mapping to the CORBA OTS (Object Transaction Service). Comment
The EJB specification defines interoperability with CORBA through compatibility with CORBA protocols. This is achieved by mapping EJB services such as JTS and JNDI to corresponding CORBA services and the implementation of RMI on top of the CORBA protocol IIOP. Comment
Use of CORBA and RMI/IIOP in Enterprise JavaBeans is implemented in the EJB Container and is the responsibility of the EJB Container provider. Use of CORBA and RMI/IIOP in the EJB Container is hidden from the EJB Component itself. This means that the Enterprise Bean Provider can write their EJB Component and deploy it into any EJB Container without any regard of which communication protocol is being used. Comment
An EJB consists of a number of pieces, including the Bean itself, the implementation of some interfaces, and an information file. Everything is packaged together into a special jar file. Comment
The Enterprise Bean is a Java class that the Enterprise Bean Provider develops. It implements an Enterprise Bean interface and provides the implementation of the business methods that the component is to perform. The class does not implement any authorization, authentication, multithreading, or transactional code. Comment
Every Enterprise Bean that is created must have an associated Home interface. The Home interface is used as a factory for your EJB. Clients use the Home interface to find an instance of your EJB or create a new instance of your EJB. Comment
The Remote interface is a Java Interface that reflects the methods of your Enterprise Bean that you wish to expose to the outside world. The Remote interface plays a similar role to a CORBA IDL interface. Comment
The deployment descriptor is an XML file that contains information about your EJB. Using XML allows the deployer to easily change attributes about your EJB. The configurable attributes defined in the deployment descriptor include:
The EJB-Jar file is a normal java jar file that contains your EJB, Home and Remote interfaces, as well as the deployment descriptor. Comment
Once you have an EJB-Jar file containing the Bean, the Home and Remote interfaces, and the deployment descriptor, you can fit all of the pieces together and in the process understand why the Home and Remote interfaces are needed and how the EJB Container uses them. Comment
The EJB Container implements the Home and Remote interfaces that are in the EJB-Jar file. As mentioned earlier, the Home interface provides methods to create and find your EJB. This means that the EJB Container is responsible for the lifecycle management of your EJB. This level of indirection allows for optimizations to occur. For example, 5 clients might simultaneously request the creation of an EJB through a Home Interface, and the EJB Container would respond by creating only one EJB and sharing it between all 5 clients. This is achieved through the Remote Interface, which is also implemented by the EJB Container. The implemented Remote object plays the role of a proxy object to the EJB. Comment
All calls to the EJB are proxied through the EJB Container via the Home and Remote interfaces. This indirection is the reason why the EJB container can control security and transactional behavior. Comment
The Enterprise JavaBeans specification defines different types of EJBs that have different characteristics and behaviors. Two categories of EJBs have been defined in the specification: Session Beans and Entity Beans, and each categoriy has variations. Comment
Session Beans are used to represent Use-Cases or Workflow on behalf of a client. They represent operations on persistent data, but not the persistent data itself. There are two types of Session Beans, Stateless and Stateful. All Session Beans must implement the javax.ejb.SessionBean interface. The EJB Container governs the life of a Session Bean. Comment
Stateless Session Beans are the simplest type of EJB component to implement. They do not maintain any conversational state with clients between method invocations so they are easily reusable on the server side and because they can be cached, they scale well on demand. When using Stateless Session Beans, all state must be stored outside of the EJB. Comment
Stateful Session Beans maintain state between invocations. They have a one-to-one logical mapping to a client and can maintain state within themselves. The EJB Container is responsible for pooling and caching of Stateful Session Beans, which is achieved through Passivation and Activation. If the EJB Container crashes, data for all Stateful Session Beans could be lost. Some high-end EJB Containers provide recovery for Stateful Session Beans. Comment
Entity Beans are components that represent persistent data and behavior of this data. Entity Beans can be shared among multiple clients, the same way that data in a database can be shared. The EJB Container is responsible for caching Entity Beans and for maintaining the integrity of the Entity Beans. The life of an Entity Bean outlives the EJB Container, so if an EJB Container crashes, the Entity Bean is still expected to be available when the EJB Container again becomes available. Comment
There are two types of Entity Beans: those with Container Managed persistence and those with Bean-Managed persistence. Comment
Container Managed Persistence (CMP). A CMP Entity Bean has its persistence implemented on its behalf by the EJB Container. Through attributes specified in the deployment descriptor, the EJB Container will map the Entity Beans attributes to some persistent store (usuallybut not alwaysa database). CMP reduces the development time for the EJB, as well as dramatically reducing the amount of code required. Comment
Bean Managed Persistence (BMP). A BMP Entity Bean has its persistence implemented by the Enterprise Bean Provider. The Enterprise Bean Provider is responsible for implementing the logic required to create a new EJB, update some attributes of the EJBS, delete an EJB and find an EJB from persistent store. This usually involves writing JDBC code to interact with a database or other persistent store. With BMP, the developer is in full control of how the Entity Bean persistence is managed. Comment
BMP also gives flexibility where a CMP implementation may not be available. For example, if you wanted to create an EJB that wrapped some code on an existing mainframe system, you could write your persistence using CORBA. Comment
As an example, the Perfect Time example from the previous RMI section will be implemented as an EJB component. The example will be a simple Stateless Session Bean. Comment
As mentioned earlier, EJB components consist of at least one class (the EJB) and two interfaces: the Remote and Home interfaces. When you create a Remote interface for an EJB , you must follow these guidelines: Comment
Here is the simple remote interface for the PerfectTime EJB:
//: c15:ejb:PerfectTime.java //# You must install the J2EE Java Enterprise //# Edition from java.sun.com and add j2ee.jar //# to your CLASSPATH in order to compile //# this file. See details at java.sun.com. // Remote Interface of PerfectTimeBean // {Depends: j2ee.jar} import java.rmi.*; import javax.ejb.*; public interface PerfectTime extends EJBObject { public long getPerfectTime() throws RemoteException; } ///:~
The Home interface is the factory where the component will be created. It can define create methods, to create instances of EJBs, or finder methods, which locate existing EJBs and are used for Entity Beans only. When you create a Home interface for an EJB , you must follow these guidelines:
The standard naming convention for Home interfaces is to take the Remote interface name and append Home to the end. Here is the Home interface for the PerfectTime EJB: Comment
//: c15:ejb:PerfectTimeHome.java // Home Interface of PerfectTimeBean. // {Depends: j2ee.jar} import java.rmi.*; import javax.ejb.*; public interface PerfectTimeHome extends EJBHome { public PerfectTime create() throws CreateException, RemoteException; } ///:~
You can now implement the business logic. When you create your EJB implementation class, you must follow these guidelines, (note that you should consult the EJB specification for a complete list of guidelines when developing Enterprise JavaBeans): Comment
//: c15:ejb:PerfectTimeBean.java // Simple Stateless Session Bean // that returns current system time. // {Depends: j2ee.jar} import java.rmi.*; import javax.ejb.*; public class PerfectTimeBean implements SessionBean { private SessionContext sessionContext; //return current time public long getPerfectTime() { return System.currentTimeMillis(); } // EJB methods public void ejbCreate() throws CreateException {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext ctx) { sessionContext = ctx; } }///:~
Because this is a simple example, the EJB methods (ejbCreate( ), ejbRemove( ), ejbActivate( ), ejbPassivate( ) ) are all empty. These methods are invoked by the EJB Container and are used to control the state of the component. The setSessionContext( ) method passes a javax.ejb.SessionContext object which contains information about the components context, such as the current transaction and security information. Comment
After we have created the Enterprise JavaBean, we then need to create a deployment descriptor. The deployment descriptor is an XML file that describes the EJB component. The deployment descriptor should be stored in a file called ejb-jar.xml. Comment
//:! c15:ejb:ejb-jar.xml <?xml version="1.0" encoding="Cp1252"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'> <ejb-jar> <description>Example for Chapter 15</description> <display-name></display-name> <small-icon></small-icon> <large-icon></large-icon> <enterprise-beans> <session> <ejb-name>PerfectTime</ejb-name> <home>PerfectTimeHome</home> <remote>PerfectTime</remote> <ejb-class>PerfectTimeBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <ejb-client-jar></ejb-client-jar> </ejb-jar> ///:~
You can see the Component, the Remote interface and the Home interface defined inside the <session> tag of this deployment descriptor. Deployment descriptors may be automatically generated using EJB development tools. Comment
Along with the standard ejb-jar.xml deployment descriptor, the EJB specification states that any vendor specific tags should be stored in a separate file. This is to achieve high portability between components and different brands of EJB containers. Comment
The files must be archived inside a standard Java Archive (JAR) file. The deployment descriptors should be placed inside the /META-INF sub-directory of the Jar file. Comment
Once the EJB component is defined in the deployment descriptor, the deployer should then deploy the EJB component into the EJB Container. At the time of this writing, the deployment process was quite GUI intensive and specific to each individual EJB Container, so this overview does not document that process. Every EJB Container, however will have a documented process for deploying an EJB. Comment
Because an EJB component is a distributed object, the deployment process should also create some client stubs for calling the EJB component. These classes should be placed on the classpath of the client application. Because EJB components can be implemented on top of RMI-IIOP (CORBA) or RMI-JRMP, the stubs generated could vary between EJB Containers; nevertheless they are generated classes. Comment
When a client program wishes to invoke an EJB, it must look up the EJB component inside JNDI and obtain a reference to the home interface of the EJB component. The Home interface is used to create an instance of the EJB. Comment
In this example the client program is a simple Java program, but you should remember that it could just as easily be a servlet, a JSP or even a CORBA or RMI distributed object.
//: c15:ejb:PerfectTimeClient.java // Client program for PerfectTimeBean // {Depends: j2ee.jar} public class PerfectTimeClient { public static void main(String[] args) throws Exception { // Get a JNDI context using // the JNDI Naming service: javax.naming.Context context = new javax.naming.InitialContext(); // Look up the home interface in the // JNDI Naming service: Object ref = context.lookup("perfectTime"); // Cast the remote object to the home interface: PerfectTimeHome home = (PerfectTimeHome) javax.rmi.PortableRemoteObject.narrow( ref, PerfectTimeHome.class); // Create a remote object from the home interface: PerfectTime pt = home.create(); // Invoke getPerfectTime() System.out.println( "Perfect Time EJB invoked, time is: " + pt.getPerfectTime() ); } } ///:~
The sequence of the example is explained in the comments. Note the use of the narrow( ) method to perform a kind of casting of the object before a Java cast is performed. This is very similar to what happens in CORBA. Also note that the Home object becomes a factory for PerfectTime objects. Comment
The Enterprise JavaBeans specification is a dramatic step forward in the standardization and simplification of distributed object computing. It is a major piece of the Java 2 Enterprise Edition (J2EE) platform and is receiving much support from the distributed object community. Many tools are currently available or will be available in the near future to help accelerate the development of EJB components. Comment
This overview was only a brief tour of EJBs. For more information about the EJB specification you should see the official Enterprise JavaBeans home page at java.sun.com/products/ejb/, where you can download the latest specification and the J2EE reference implementation. These can be used to develop and deploy your own EJB components. Comment
[95] This section was contributed by Robert Castaneda, with help from Dave Bartlett.