Sie sind auf Seite 1von 93

INTRODUCTION

Welcome to this course on Enterprise JavaBeans. Enterprise JavaBeans is popularly abbreviated


as EJB. We will be dealing with all the concepts involved in this Technology and guide you step-
by-step through the theory. A few examples will also be dealt with in detail.
COURSE ORIENTATION AND ROADMAP
The course is designed by a panel of experts. It has undergone rigorous evaluation and only then
been approved. The approach is such that it explains maximum possible concepts.
First, the student will be introduced to the software requirements. This will include installation
instructions as well.

The actual course will be an exhaustive tour of the Enterprise JavaBeans technology world with
relevant illustrations source codes. Go through each lesson carefully and make sure you have
understood the explanation and the logic involved.
PREREQUISITES
The course demands that the individual have

ESSENTIAL:
• Knowledge of the Java Run Time Environment (JRE) and Java Programming.

• Knowledge of Database connectivity using JDBC.

• Basic knowledge of Servlets.

OPTIONAL:

• Familiarity with topics in Object Oriented Programming and Distributed Architecture will
be an added advantage.

Other than this not much is required to undertake the course.


SOFTWARE PREREQUISITES
You need to have
• JDK 1.2 or higher.

• Java 2 Enterprise Edition (J2EE).

We will be using the J2EE server for our examples.

The JDK and J2EE can be freely downloaded from Sun MicroSystem's web site. The JDK
package (zipped version) is around 20 Mb in size and the J2EE around 12 Mb. It would be
beneficial to have the documentation downloaded as well for ready reference.
HARDWARE REQUIREMENTS

The minimum hardware requirements are listed below


• Pentium II Processor and onwards.

• 300 MB Free HardDisk Space (Software + Documentation).

• 64 MB RAM (128 MB RAM recommended).

The configuration of the machines in our laboratories on which the examples were tested were

• 450 MHz Pentium III Processor

• 128 MB RAM

The Operating System used by us:

• Windows NT
INSTALLING THE JDK

The JDK comes as a single bundled file. Just double click the downloaded file to install it. Follow
the instructions on screen. You will be prompted for the destination directory for the software You
can choose to install the software in the default folders specified or indicate a folder of your
choice. It is better to install the JDK and JRE in different directories.
• The CLASSPATH and Path variables have to be updated to include the JDK's "rt.jar" file
and the "bin" folder, respectively.
INSTALLING THE J2EE
The J2EE comes as a single bundled file. Just double click the downloaded file to install it. Follow
the instructions on screen. You will be prompted for the destination directory for the software You
can choose to install the software in the default folders specified or indicate a folder of your
choice.
• The CLASSPATH must be updated to include the j2ee.jar file. The "bin" folder must be
included in the path variable.
ENTERPRISE ARCHITECTURE

The age has come when transaction of any nature will be carried out online through the web -
instantaneously. As more business is conducted over the network, enterprises find they can
achieve more with less, they can interact with their customers and business partners more quickly
and cheaply using networked business-to-business and business-to-consumer applications.
These enterprises are conducting e-business. To realize this distributed project we need to have
an Enterprise Server.

• The Enterprise Server will almost certainly be connected to a database for persistent
storage of information. The Enterprise Server consists of an Application Server and a
Web Server.

• The Enterprise Server will also be connected to a local intranet where the company
employees have an access to the server.

• All correspondence with the outside wall will have to be directed through a firewall. A
firewall basically provides the Security feature which is very crucial. With this architecture
virtually anyone who has internet access can approach the Server with a request and
may be granted it provided he has the appropriate privileges. Privileges can be controlled
by the Firewall

• Web Server provides the presentation layer to the clients. A typical Web servers talks
HTTP with clients, with an application server being the middle tier that talks to the
database. The Web and application server usually run in different process spaces
MULTI-TIER ARCHITECTURE

Two Tier Architecture:

• Earlier the emphasis was on the two - tier architecture. This was the traditional Client-
Server approach.

• This meant that the business logic involved had to be incorporated on the client side.

• All the processing of business logic is done on the client side which is not reliable
because business critical data should be hidden from the user.

Multi-Tier Architecture:

• The need to have more light weight clients prompted the multi - tier architecture to take
birth.

• The client no longer had to be bothered about the business logic. This made way for thin
clients.

• The introduction of the Middle - Tier shifted the burden of business logic to the middle
layer.

• These business objects would be responsible for helping the client to perform required
operations on the server transparent to the client.
The role of the business object is a classic example for utilizing Enterprise JavaBeans which can
encapsulate the business logic.
In multi-tier architecture client is sitting on a dumb terminal. He has only a front end. All the
business logic and services are in the middle tier (Application Server)

An ideal practice is to place stateless or light-state objects (which don’t need to carry a reliable
state) onto the front-end Web server, while keeping more complex objects on the application
server. This often translates into keeping static HTML, content files and JSPs on the Web server,
and transactional applications on the application server.
EJB OVERVIEW

Enterprise JavaBeans (abbreviated as EJB) is a server-side component model for component


transaction monitors. EJB objects can be used for applications in a distributed environment. EJB
architecture represents a component architecture. The EJB object has to be deployed on a
Server so that it can be made accessible to a client requiring it's services.
What benefits do an application built using EJB provide ?
The benefits include

• scalability

• transaction management

• security

• persistence

• concurrency control.

We'll discuss each of these topics in detail later.

The advantage EJB provides to a developer is that he can concentrate his efforts on writing the
business logic required rather than worrying about the complexities involved with the architectural
framework. The object is usually part of the middle tier in a multi-tier architecture. EJB technology
as a whole provides a framework into which Java Components can be deployed.
EJB OVERVIEW (contd...)

A wonderful thing is that an EJB component can be deployed on any application server provided
it sticks to the EJB specifications. So it doesn't matter whether the Server is of BEA's WebLogic
or Sun Microsystem's J2EE (Java 2 Enterprise Edition).
It will be assumed that the reader is familiar with Java programming.

However, in our course material we will be describing how the beans are to be deployed on the
J2EE Server. The same source code with some minimal changes can be used. It's only the
deployment process which differs and is vendor specific. Deployment in WebLogic requires that
the properties file be modified each time. It however also provides a Deployment Wizard which
does simplify the process.

The database used will be Cloudscape which is a pure Java database. An evaluation version of
this is packaged in the J2EE itself. So you don't have to download any additional software for this
purpose. You can also connect to other database systems using the appropriate JDBC drivers.

After this humble beginning let us go into greater details.


EJB OVERVIEW (contd...)

Lets us look at the scenario in a little more technical perspective.

As shown in the figure the layer at the client side is the presentation layer. The EJB architecture
enables the client to be fairly thin and lightweight. This layer is unburdened of business logic. This
is the first Tier in a multi-layer architecture.

The middle layer encapsulates the complex business logic. An EJB object is an ideal candidate to
play this role. CORBA's ORB (Object Request Broker) and COM object's can also be used but
there are certain important aspects which make the EJB a preferable choice. An ORB is
inadequate for high volume-transactional environments. Also the services, in case of an EJB, are
handled by the container. In the case of ORB's this has to be taken care of by the developer and
coded for.

The backend represents the database access and transactions. Not all beans need to connect to
a database. But it's difficult to visualize a real-time application which doesn't need to store some
form of data or the other.

We'll try and understand the important concept of a stub and skeleton in the next lesson.
What is a Client and a Remote Object?
A Client is any entity which avails of a service.
The remote object which provides the service, can reside on the same or a different
machine/network on which the client is located. When this service is provided by remote objects
located on different server's it becomes distributed. The services (methods) provided by the
remote object are specified in it's interface. But how does the Client locate the remote object? It
generally accomplishes this by employing a Naming Service like JNDI (Java Naming and
Directory Interface).

Once the remote object (such as our enterprise bean) is deployed on a Server it waits for
request's from Client's. There is nothing that prevents a remote object from itself being a client to
another remote object.

A typical analogy would be an ATM machine setup which waits for customers (clients) to use it.
The customer knows the geographical location of the machine as it might have typically been
listed in the ATM brochure (Naming Service). The customer can specify the amount he desires to
withdraw after entering his ATM number and password (ATM's Interface). The ATM machine will
need to access a database storage to check whether the account is valid and confirm that it is not
overdrawn (The Server itself behaving as a client to another object which in this case handles
queries and transactions on the database)
THE PIECES ON THE SERVER SIDE IN A NUTSHELL.
An enterprise bean resides in a container on the Server. The container should not be thought of
as a physical construct.
The Enterprise Bean has two interfaces and an implementation class.

1) Home Interface : The bean has a home interface and also creates an EJB Object when a
client requests for it. It has methods which are called for creating and removing a bean. Thus it
can be thought of as a bean factory.

2) Remote interface : There is also a remote interface which contains the business methods
of the bean.

3) Bean Class : The Home Interface and Remote Interface only contain method declarations
while the actual implementations are provided for in the bean class itself.

This represents, in short, the situation on the Container's side. All these units will be explained in
detail in the subsequent pages.
CONTAINER
Let's now see what a Container is and what functions it performs. On the Server the remote
object resides within a Container. It presents a uniform interface between the bean and the
Server. Thus the beans may be considered to be managed by the Container. The existence of a
container is transparent to the Client.
CONTAINER (contd...)

The container performs certain services on behalf of the bean. These services include:
Persistence This is done by either storing or loading the bean's state to a
persistent storage.
Naming and lookup It publishes the home interface for the EJB Object with a particular
services name in the JNDI namespace.
Security Validity of access to the bean can be verified. Access can be
restricted to a limited number
Transaction Management To ensure that the data in the database and that available to any
EJB Object at any point of time, the transaction attributes can
be specified based on which the container knows how transactions
are to be managed.
Lifecycle creation, initialization and removal of the bean
State Management the bean class is informed of changes to state with the help of
Callback methods
Factory The client of a bean requests the bean factory to create a bean
instance with some initial set of values. Each type of bean, not
each instance, has its own factory
Concurrency Enforces concurrency control to ensure that data is not corrupted.

The Container and the EJB Object work in tandem to implement the services required by a
container.

The container is responsible for creating new instances of the beans and adding it to the bean
pool (we'll describe the meaning of this later). The container also stores the state of the bean onto
secondary storage and refreshes the state from it when it is requested. For lookup of a bean by
the Client it is necessary to have a name for this purpose. The container associates the stub with
the appropriate JNDI name it is registered under. If any method of the bean requires a database
connection the Container does it on behalf of the bean.
STUBS AND SKELETONS
In this lesson we will try and understand what stubs and skeletons are and where they fit into the
multi-tier architecture picture. How does the client learn about the methods of the remote object?
And further more how does it access those methods, pass values and retrieve results? To answer
this question let us look at how the process "ticks". When the client approaches the Server
seeking the services of a bean, the client is provided with a "stub" of the remote bean.
STUBS AND SKELETONS (contd....)
The stub is nothing but the client side proxy of the bean. It contains information on the methods
available in the bean itself. It also helps the client to connect to the instance of the remote object.
Mind you, the stub only has matching methods in it and not the actual implementation. This
almost makes it seem that the remote object is located on the client's machine itself. These
matching methods on the stub contain code which makes the forwarding of requests to the
remote object and receiving the results from it possible. And this is precisely what is desired as
the business logic will be hidden from the client since it really doesn't concern him.
The "skeleton" wraps the instance of the remote object on the Server side. It listens for calls from
the stub. The skeleton conceals the remote object from the networking details.

For each remote object there is a tailormade stub and skeleton designed specifically for it.
Consider two remote objects called Account and Customer. The Account object will have a
matching Account Stub and Account Skeleton classes. And likewise the Customer class will have
a corresponding Customer Stub and Customer Skeleton class. The Account Stub will not work in
place of Customer Stub and vice-versa.
EJB OBJECT
There is a natural logical query that should have come up in your mind by now… . How does the
Bean Class have knowledge of the methods in the Remote Interface if it does not extend it? This
is done with the help of something known as an "EJB Object". This is not generally visible as it is
implemented by the vendor. It is like a wrapper to the bean class.
The main reason why this is done is to ensure that the client cannot bypass the container and call
the bean method directly

The EJB Object works in tandem with the container to enforce services like security, transactions
etc. This is more than sufficient to know about the EJB Object right now.
REMOTE INTERFACE
As the name suggests the remote interface is an interface. Which means that only the declaration
of the methods of the bean are present in this. The implementation of these methods are
provided in a separate class which we shall see soon. This interface in turn extends the
javax.ejb.EJBObject interface. Let us quickly review the methods defined by this interface
(javax.ejb.EJBObject).

1) EJBHome getEJBHome( )
Returns a reference to the enterprise Bean's home interface. The home interface will be
explained to you in the next lesson.

2) Handle getHandle( )
Obtains a handle for the EJB Object. (Handles will be taught in a separate lesson at the end of
the course).

3) java.lang.Object getPrimaryKey( )
Obtain the primary key of the EJB Object.

4) boolean isIdentical(EJBObject obj)


Used to check whether the EJB object under consideration is identical to the invoked EJB Object.

5) void remove( )
Remove the EJB object.
For example the Account bean would logically have a method to check the balance in the
customers account. There would also be methods that allow an amount to be debited or credited
into the account.
When we actually analyze a complete bean code the above methods will be clear.
HOME INTERFACE
This interface contains methods which can create new instances of beans and remove them. The
Home interface extends the javax.ejb.EJBHome interface. The Home interface can also include
some "Finder" methods (These are basically methods defined to look up beans and are defined in
case of Entity beans and not for Session Beans). For each of the create, remove and Finder
methods defined there must be a corresponding method in the actual bean class with an "ejb"
prefix. For example, if there is a method called "Create( )" in the Home interface then there must
be a corresponding "ejbCreate( )" defined in the bean class. (The Bean Class is described in the
next lesson). What does the interface javax.ejb.EJBHome look like?
The definition is as follows:

public interface EJBHome extends java.rmi.Remote{


EJBMetaData getEJBMetaData( )
// Obtain the EJBMetaData interface for the enterprise Bean. The
// EJBMetaData interface allows a client to obtain the enterprise
// Bean's information. For e.g. whether it is a session bean or not,
// whether it is a
// stateful or stateless bean,etc.

HomeHandle getHomeHandle( )
//Obtain a handle for the home object.
void remove(Handle handle)
//Remove an EJB object identified by its handle.

void remove(java.lang.Object primaryKey)


//Remove an EJB object identified by its primary key.
}
BEAN CLASS
Finally we come to the class which actually provides the implementation (code) of the methods in
the Remote Interface and the Home Interface. The business logic is taken care of in this class.
Now the sense in separating the business logic from the networking details can be appreciated.
The business logic is what varies from bean to bean. The technique employed to pass method
requests, parameters, etc. (In short… . The Networking, marshalling and de-marshalling aspects)
is similar and pretty standard, so the developer can be spared of this task.

The Bean Class implements either

1. javax.ejb.EntityBean, or,

2. javax.ejb.SessionBean

Which one of the above interfaces is to be implemented will depend on whether the bean being
developed is an Entity or a Session Bean.

This class must be declared public to allow the container to introspect the methods while
generating the support classes required for the bean.
SEQUENCE OF EVENTS
Let's take a sequential look at how things work in this setup. The sequence of Events which occur
right from the creation of the bean to when it services a client can be summed up as follows:
STEP 1 : The Container creates the Home Object on the server which listens to
requests from clients.

STEP 2 : The Container uploads the Home Object's stub and registers it with the
Naming Service.
SEQUENCE OF EVENTS (contd...)
STEP 3 : The Client does a lookup using the name under which the bean is registered
with the JNDI.

STEP 4 : The Client then downloads the Home Stub from the JNDI.
SEQUENCE OF EVENTS (contd...)
STEP 5 : Using the ejbCreate( ) method in the Home Stub the client asks the
container to create an instance of the bean.

STEP 6 : The container creates an instance of the bean and the EJB Object
SEQUENCE OF EVENTS (contd...)
STEP 7 : A reference to the EJB Object (which is nothing but the stub) is returned to
the client.

STEP 8 : Using this remote reference the Client can invoke the methods of the bean.
STEP 9 : After use the Client can request the Container to remove the bean by explicitly calling
the remove( ) method or it can optionally be added to the bean pool. A bean pool is nothing but a
collection of bean instances.
TYPES OF BEANS
There are basically two types of beans. A bean can either be a
1) Session Bean
2) Entity Bean.

A Session bean can be further classified as


1) Stateless
2) Stateful

The Entity bean can be further classified as


1) Bean Managed Persistence
2) Container Managed Persistence

Whether a bean qualifies as a Session or Entity Bean depends on what the Bean represents or is doing.

An Entity Bean generally represents data in a database and are persistent in nature. For example consider a customer
"Thomas". He can be represented by an Entity bean since he represents data in the database. There may also be othe
which describe the customer more fully, for example his age, sex, Social Security number, etc.

On the other hand Session Beans usually define tasks or processes. Consider a bean which calculates the present val
investment based on the Principal amount, the interest rate and the time period provided to it. This can be accomplish
Session Bean.

Note: It is important to grasp the concept that a Session Bean may also access, update or delete data in the database
doesn't represent the data itself.

An Entity Bean instance can be accessed by more than one client at a time.

A Session Bean instance can be accessed by only a single client at a time.

Next, we will look at the characteristics of each type of bean in detail.


SESSION BEANS
As it was mentioned in the previous lesson a Session Bean usually represents a task or a
process. Session Beans can access data in the database but does not represent it. A session
bean can be created by defining a class that implements the javax.ejb.SessionBean interface.
Session Beans are not persistent, meaning the bean is not saved to a database. A session bean
can work in combination with an Entity Bean. There are certain advantages of using this
technique as well which will be better understood after the lesson on Entity Bean is covered.
There are certain characteristics of Session Beans:

• It services a single client at a time.

• May update shared data in the database, but it does not directly
represent the shared data.

• Is relatively short-lived and is lost if the container/Server crashes.

Session beans may be optionally be destroyed by the container if it is inactive for sometime and a
time-out has occurred.

Session Beans can be either stateless or stateful. We'll explore these next.
STATELESS SESSION BEANS

Firstly, let's examine the stateless Session Bean. A stateless bean is one which does not
maintain any state information between method calls. A session bean is normally not passivated
as it does not have any state to maintain. ("Passivation" is the process of writing the state of the
bean to a persistent storage and "Activation" is exactly the reverse).
When the bean is out of use the container has the option of destroying the bean instance. If the
client then invokes a business method on the remote stub then the container will instantiate a
new session bean.

A stateless session bean is not dedicated to one client but can service multiple clients (Not
Simultaneously). This is because the state need not be saved. Thus it does not matter to the
client which bean is servicing him and he is unaware of this. So, it is possible to swap an instance
with another.
BEAN POOL
Whenever a Client requests for the services of a bean an instance of the bean is what is made
available to service it. Thus, a container will make provisions to pool together bean instances for
this purpose. This pool is called a bean pool or more specifically an instance pool. This form of
pooling helps in better resource management. In addition, it automatically introduces the benefit
of reusability and resource conservation.

When the requirement of bean instances increases the container can create new instances as
and when required. So an instance can be thought of to exist in two basic states:
• Pooled state: The instance is in the bean pool. It could be there as a result of being
created, swapped or returned after servicing the request.

• Ready state: The instance is called from the bean pool to service a client request.

Armed with this knowledge we can now understand what instance swapping is.
INSTANCE SWAPPING
Stateless Session beans instances are specially empowered with the ability of
instance swapping. This basically means that if the bean instance is servicing
a particular EJB Object, it can be swapped in between with another bean
instance. This is possible because the stateless session bean does not keep
it's state in it's "memory" between method invocation's. Thus it doesn't matter
which exact bean instance is servicing the request at any point of time. Now it
must be apparent to you that stateful Session beans cannot participate in a
similar exercise.
A developer doesn't actually have to be concerned with any of this as it is
handled by the container.
DEVELOPING A FIRST SESSION BEAN
This module aims at showing you how a simple Session Bean can be written, and then deployed.
We will also create a Client which will access the method of the bean. This is a very simple and
basic Stateless Session Bean. It doesn't render justice to the immense capabilities of a bean.
Nevertheless, it is a beginning. The bean also does not communicate with any other bean.
Obviously, it's utility is limited but will suffice to explain certain basic ideas and will give a feel of
things to follow:
The function of the bean is to calculate the product of two numbers passed to one of it's methods
as parameter's and return the answer to the Client program.

Obviously, this is a stateless bean as the state need not be saved. There are four classes. These
are

• Multiplier.java

• MultiplierHome.java

• MultiplierEJB.java

• MultiplierClient.java.

Multiplier.java is the remote interface. MultiplierHome is the Home interface. MultiplierEJB is the
EJB Object class which provides the implementation for the Remote Interface. And
MultiplierClient.java as the name suggests is the client class which makes a request to server for
the bean.

Let us now put all the pieces together.


THE "Multiplier" INTERFACE
This is the remote interface of the bean.
The interface simply declares a single method called multiply which takes two double values as
parameters and returns the product. It can throw a RemoteException.
The definition of this interface is as shown below:

//Multiplier.java

import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Multiplier extends EJBObject {
public double multiply(double no1,double no2) throws Remote
Exception;
}

Notice that it extends another interface javax.ejb.EJBObject which itself extends java.rmi.Remote.
THE "MultiplierHome" INTERFACE
This is the Home interface of the MultiplierEJB Bean. As expected it extends the
javax.ejb.EJBHome interface. It defines a create( ) method which returns a reference to a
Multiplier bean instance which was created.
The method can throw a RemoteException or a CreateException.

// MultiplierHome.java

import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface MultiplierHome extends EJBHome {


Multiplier create( ) throws RemoteException, CreateException;
}

Since this is a Session Bean there is no need to declare any finder methods as there will be no
need to search for another bean.
THE "MultiplierEJB" CLASS
This is the class which actually implements the methods in the Multiplier interface. It implements
the javax.ejb.SessionBean interface since it is a Session Bean.
Examine the methods in the class:

// MultiplierEJB.java

import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

public class MultiplierEJB implements SessionBean {

public double multiply(double no1,double no


2) {
return no1*no2;
}

public MultiplierEJB( ) {
//no implementation
}

public void ejbCreate( ) {


//no implementation
}

public void ejbRemove( ) {


//no implementation
}

public void ejbActivate( ) {


//no implementation
}

public void ejbPassivate( ) {


//no implementation
}

public void setSessionContext(SessionContext sc) {


//no implementation
}
}

The first method implements the method declared in the Multiplier interface. It returns a double
value which is the result. There is an ejbCreate( ) method which is called for creation of a bean
instance. The remaining are callback methods and are more relevant for stateful session and
entity beans. So, we'll postpone our discussion till we see an Entity bean example.
COMPILING AND DEPLOYING THE SESSION BEAN
Compiling the source files:
Follow the steps below:

1. Store the three files viz. Multiplier.java, MultiplierHome.java and MultiplierEJB.java in the
adirectory where you usually store your examples.

2. Compile the three files by using the javac comand

Directory> javac Multiplier.java


Directory> javac MultiplierHome.java
Directory> javac MultiplierEJB.java
This will generate three .class files in the same directory.
STARTING THE SERVER, DEPLOYTOOL AND CREATING THE MULTIPLIER.EAR FILE.

3. Start the J2EE Server by typing the following command at the prompt
C:> J2EE -verbose.

4. Start the deploytool by typing the following command a new command prompt after
changing to the directory containing the deploytool.bat file. This is in the bin folder within
your J2EE installation Directory.
path to installation directory\bin> deploytool

5. Open "File" and select "New Application". This opens a new window. Enter the
"Application Name" as "MultiplierApp". Browse and select the location of the file. Enter
the name for the file as "MultiplierApp.ear". This will add MultiplierApp to your local
"Applications window".

6. Confirm that MultiplierApp.ear file is added to the directory as well.

Note: The extension .ear stands for enterprise archive.


CREATING THE JAR FILE AND DEPLOYING THE APPLICATION

7. Click on the "File" Menu and select "New Enterprise Bean". This opens a
new Window "New Enterprise Bean Wizard". Click Next.

8. Enter the Display Name as "MultiplierEJB".

9. Press the "Add" button within "Contents".

10. Select the three .class files and say OK. Then press "Next".

11. Select classname as "MultiplierEJB", Home Interface as "MultiplierHome", Remote


Interface as "Multiplier". Enter the Display Name as "MultiplierDemo". Select bean type
as "Session" and "Stateless".

12. Press "Finish".

13. Select the "MultiplierApp" in "Local Application" of the deploytool. Go to the "JNDI
Names" tab and enter "MyMultiplier" in the "JNDI Name" field. Highlight the row and
select "save" from the "File" Menu.
14. Go to the Tools Menu and select the "Deploy Application". Tick the Return Client jar and
enter the location where your files are stored. This will cause the MultiplierAppClient.ear
file to be placed within that directory.

15. Deployment will begin and when it is complete Press "OK".


16. If deployment was successful MultiplierApp will appear in the "Server Applications"
Panel.

Congratulations, you have just deployed you first bean.

Feel free to open the ear file using WinZip to examine it's contents.
The deployment descriptor file is in the form of an XML-document.

Next we will look at the Client class which will access the bean.
THE "MultiplierClient" CLASS
We finally come to the client class which will actually access the business method on the bean.
The code is reproduced below:
// MultiplierClient.java

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

public class MultiplierClient {

public static void main(String[ ] args) {


try {
Context initial = new InitialContext( );
Object objref = initial.lookup("MyMultiplier");
MultiplierHome home =

(MultiplierHome)PortableRemoteObject.narrow(objref,MultiplierHome.class);
Multiplier multiplynumber = home.create( );
double product = multiplynumber.multiply(23.36,132.54);
System.out.println(String.valueOf(product));
} catch (Exception ex) {
System.err.println("Exception occured"+ex);
}
}
}

The class contains a main( ) method.

The client looks up the bean by its JNDI name which in this case is "MyMultiplier". A reference to
the home interface of the bean is returned which is then explicitly type-cast into one of
MultiplierHome type.

Using the create method in the home interface's stub a bean instance is created and a reference to
it (stub) is returned to the client. Using this stub the Client invokes the multiply( ) method of the
bean. The result returned is printed.
COMPILING AND RUNNING THE CLIENT
Create the following bat file and run it
set J2EE_HOME=<J2EE installation directory>
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar
javac -classpath %CPATH% MultiplierClient.java

It sets the J2EE_HOME variable if it has not already been set and includes j2ee.jar into the
CLASSPATH variable. And then it compiles the MultiplierClient.java file.

Create this second bat file and run it

set J2EE_HOME=<J2EE installation directory>


set CPATH=.;%J2EE_HOME%\lib\j2ee.jar;MultiplierAppClient.jar
java -classpath "%CPATH%" MultiplierClient

The above commands actually run the Client code. Ensure that the J2EE Server is also running.

The output reads as follows:

3096.1344
JAVABEANS vs EJB
The only similarity between JavaBeans and EJB are that they are both Component Models. Let's
look at some of the differences between the two.

JavaBeans Enterprise JavaBeans

They are almost exclusively Client- EJB components are Remote Server
Side side Components
Are either visible or non-visible
Are non-visible objects
objects
Uses the bean info Classes, Property
Uses an XML deploymetn Descriptor
Editors and Customizers to describe
file to describe itself
itself
JNDI
The Java Naming and Directory Interface (JNDI) is used for accessing naming and directory
services in Java Programs. This provides a convenient way for clients to lookup a remote object
based on a particular name. The remote object in the case of EJB reisters it's home interface with
the JNDI with a perticular name. And then the client can look up using that name.
• The object is said to be "bound" to a particular name. The Association itself is called a
"binding".

• A set of bindings is called as a "context". In a particular namespace context the name of


the object is unique.

The initialContext( ) method returns the initial context. The initial context is equivalent to the root
directory of the JNDI Name Service.

When you retreive an object from the context it is termed as "look up". This can be accomplished
by using the lookup( ) method, of the InitialContext class, passing the name to be looked up as
parameter. This returns a remote reference to the Home Stub. The reference obtained can then
be converted to a reference of the type desired by using the narrow( ) method.

Other Naming Services include

• ISO’s X.500

• OSF’s DCE

• Sun’s NIS+

• Novell’s NDS

• Internet’s LDAP

• CORBA's Cos Naming


DEVELOPING A SECOND SESSION BEAN
We will now demonstrate another stateless session bean. This bean does the task of computing
the premium amount of an investment (Principal) for a given period of time in years.
These values are passed to it as parameters to the function used to calculate the premium
amount. In this example we use the combination of an HTML page and a servlet. The user can
enter the principal amount and the duration in two textfields. When the submit button is pressed
the values are retreived by a servlet and passed to an EJB object which calculates the premium
amount and return its. The result is displayed in the form of an HTML Page.
Besides the .ear file we had created in the previos example you will also have to create a .war
file. WAR stands for Web Archive.
Lets examine all the source codes.
THE HTML CODE
The HTML code is pretty straightforward and is displayed below:

<HTML>
<BODY BGCOLOR = "WHITE">
<BLOCKQUOTE>
<H3>Loan Calculation</H3>
<FORM METHOD="GET" ACTION="LoanAlias">
<P>Enter Principal Amount:
<P>
<INPUT TYPE="TEXT" NAME="PRINCIPAL"></INPUT>
<P>Enter Number of Years:
<P>
<INPUT TYPE="TEXT" NAME="YEARS"></INPUT>
<P>
<INPUT TYPE="SUBMIT" VALUE="Submit">
<INPUT TYPE="RESET">
</FORM>
</BLOCKQUOTE>
</BODY>
</HTML>
There are two textfields named PRINCIPAL and YEARS.
THE SERVLET CLASS
The servlet code retrieves the user data, looks up the session Bean, passes the data to the
session Bean, and upon receiving a value back from the session Bean displays an HTML page to
show the returned value to the user.

//LoanServlet.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;

public class LoanServlet extends HttpServlet


{
LoanHome loanhome;
Loan loan;
public void init(ServletConfig config)throws ServletException
{
try
{
InitialContext context = new InitialContext();
//Lookup the Loan bean using it's JNDI name "MyLoan"
Object objref = context.lookup("MyLoan");
loanhome =(LoanHome)PortableRemoteObject.narrow(objref,
LoanHome.class);
}
catch (Exception NamingException)
{
NamingException.printStackTrace();
}
}
public void doGet (HttpServletRequest request, HttpServletResponse
response)throws ServletException, IOException
{
double years = 0.0;
double principal = 0.0;
double premium = 0.0;
PrintWriter out;
response.setContentType("text/html");
String title = "Loan Calculation Illustration";
out = response.getWriter();
out.println("<HTML><HEAD><TITLE>");
out.println(title);
out.println("</TITLE></HEAD><BODY>");
try
{
String principalstringtemp =
request.getParameter("PRINCIPAL");
//Retrieving value from PRINCIPAL textfield of HTML page
Double principaldoubletemp = new
Double(principalstringtemp);
principal = principaldoubletemp.doubleValue();
String yearstringtemp = request.getParameter("YEARS");
//Retrieving value from YEARS textfield of HTML page
Double yearsdoubletemp = new Double(yearstringtemp);
years = yearsdoubletemp.doubleValue();
loan = loanhome.create();
//Calculate the premium amount
premium = loan.calculateLoan(principal, years);
}
catch(Exception CreateException)
{
CreateException.printStackTrace();
}
out.println("<H1>Loan Calculation</H1>");
out.println("<P>Principal: " + principal + "<P>");
out.println("<P>Years: " + years + "<P>");
out.println("<P>Premium Value: " + premium + "<P>");
out.println("</BODY></HTML>");
out.close();
}

}
THE "Loan" INTERFACE
This interface declares one method calculateLoan which takes two parameters of type double.
The value of premium amount is calculated and returned as a double value.
//Loan.java

import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Loan extends EJBObject
{
public double calculateLoan(double principal, double years)throws
RemoteException;
}
THE "LoanHome" INTERFACE
The Home interface is as follows:
//LoanHome.java

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface LoanHome extends EJBHome


{
Loan create() throws CreateException,RemoteException;
}
THE "LoanEJB" CLASS
The Bean class is as follows:
// LoanEJB.java

import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
public class LoanEJB implements SessionBean
{
public double calculateLoan(double principal,double years)
{
double premium = principal*(1 + 0.1*years);
//Interest rate is 10%
return premium;
}

public void ejbCreate() { }


public void setSessionContext(SessionContext ctx) { }
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbLoad() { }
public void ejbStore() { }
}
STEPS TO DEPLOYING THE ENTITY BEAN
Let us look at how we can deploy this bean in the J2EE Server.
Follow the steps below:

1. Store the five files viz. Loan.java, LoanHome.java, LoanEJB.java, Loan.html and
LoanServlet.java in the directory where you usually store your examples.

2. Compile the four files by using the javac comand

Directory> javac Loan.java


Directory> javac LoanHome.java
Directory> javac LoanEJB.java
Directory> javac LoanServlet.java
This will generate four .class files in the same directory.
STARTING THE SERVER, DEPLOYTOOL AND CREATING THE LOANAPP.EAR FILE.

3. Start the J2EE Server by typing the following command at the prompt

C:> J2EE -verbose.

4. Start the deploytool by typing the following command a new command prompt after
changing to the directory containing the deploytool.bat file. This is in the bin folder within
your J2EE installation Directory.

path to installation directory\bin> deploytool

5. Open "File" and select "New Application". This opens a new window. Enter the
"Application Name" as "LoanApp". Browse and select the location of the file. Enter the
name for the file as "LoanApp.ear". This will add LoanApp to your local "Applications
window".

6. Confirm that LoanApp.ear file is added to the directory as well.

Note: The extension .ear stands for enterprise archive.


CREATING THE JAR FILE AND DEPLOYING THE APPLICATION

7. Click on the "File" Menu and select "New Enterprise Bean". This opens a
new Window "New Enterprise Bean Wizard". Click Next.

8. Enter the Display Name as "LoanEJB".

9. Press the "Add" button within "Contents".

10. Select the three .class files and say OK. Then press "Next".

11. Select classname as "LoanEJB", Home Interface as "LoanHome", Remote Interface as


"Loan". Enter the Display Name as "LoanDemo". Select bean type as "Session" and
"Stateless".

12. Skip "Environment Entries" and press "Next"

13. Skip "Enterprise Bean References" and press "Next"

14. Skip "Enterprise Resource References" and press "Next"

15. Skip "Security" and press "Next"

16. Skip "Transaction Management" and press "Next"

17. Press "Finish".

18. Select "New Web Component" from the "File" menu. Click "Next".

19. Enter "Display Name" as "LoanAppWar".

20. Press "Add".

21. Select the LoanServlet.class file and press "Add". Press "Next".

22. Select the Loan.html file and press "Add". Press "Finish".Press "Next".

23. Make sure that the "Describe a Servlet" option is ticked. Press "Next"

24. Enter "Display Name" as "LoanServlet" and press "Next".Press "Next" again.

25. In "URL Mappings" press "Add". Enter "LoanAlias" and press Finish.

26. Select the "LoanApp" in "Local Application" of the deploytool. Go to the "JNDI Names"
tab and enter "MyLoan" in the "JNDI Name" field. Highlight the row and select "save"
from the "File" Menu.

27. Click on the "Web Context" Tab in the Inspecting Window and enter the Context root for
the War File as "LoanRoot".
28. Save the application.

29. Go to the Tools Menu and select the "Deploy Application". Tick the Return Client jar and
enter the location where your files are stored. This will cause the LoanAppClient.ear file
to be placed within that directory.

30. Deployment will begin and when it is complete Press "OK".

31. If deployment was successful LoanApp will appear in the "Server Applications" Panel.
RUNNING THE PROGRAM
Open your Browser window and enter this URL in the address bar.
http://localhost:8000/LoanRoot/Loan.html

This opens an HTML page as shown below


Enter values for Principal and Years. Press submit. The premium value of the investment at 10%
interest is then displayed.
STATEFUL SESSION BEAN
A stateful session bean maintains its state across method calls. But they are not to be mistaken
as persistent. An example of this could be a shopping cart which has to maintain the items bought
by the shopper throughout the time the person is shopping.
A session bean is devoted to a single client during it's lifetime. The reason is easy to
comprehend. Since the changes in state are maintained obviously the state of the bean instance
will not be valid for another EJB Object. So this would mean that instances of stateful beans
cannot participate in instance swapping or bean pooling.
DEVELOPING A STATEFUL SESSION BEAN
This module is devoted to developing a stateful Session Bean. A shopping Cart can be a
stateless Session Bean as we need to maintain the items in the shopping cart purchased by the
Shopper. The Shopper name and Shopper Identity number are passed as parameters to the
create method.
There are four classes. These are

• ShopCart.java

• ShopCartHome.java

• ShopCartEJB.java

• ShopCartClient.java.
THE "ShopCart" INTERFACE
This is the remote interface of the bean.
The interface declares three methods - add, remove and showCart. The first two methods as the
name suggests are used to add and remove items from the Shop Cart. The last method is used
to obtain the contents of the Shop Cart. It returns vector object.
The definition of this interface is as shown below:

//ShopCart.java

import java.util.*;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface ShopCart extends EJBObject {

public void add(String itemname) throws RemoteException;


public void remove(String itemname) throws RemoteException;
public Vector showCart() throws RemoteException;

}
THE "ShopCartHome" INTERFACE
This is the Home interface of the ShopCartEJB Bean. As expected it extends the
javax.ejb.EJBHome interface. It defines a create( ) method which takes the Shopper Name and id
as parameters and returns a reference to a ShopCart bean instance which was created.
The method can throw a RemoteException or a CreateException.

// MultiplierHome.java

import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface ShopCartHome extends EJBHome {

ShopCart create(String Shopper,String ShopperId) throws


RemoteException,
CreateException;
}
THE "ShopCartEJB" CLASS
This is the class which implements the methods in the ShopCart interface. It implements the
javax.ejb.SessionBean interface since it is a Session Bean.
Examine the methods in the class:
// ShopCartEJB.java
import java.util.*;
import javax.ejb.*;

public class ShopCartEJB implements SessionBean {


String Shopper;
String ShopperId;
Vector items;

public void ejbCreate(String Shopper,String Sho


pperId)
throws CreateException {
this.Shopper = Shopper;
this.ShopperId = ShopperId;
items = new Vector();
}

public void add(String itemname) {


items.addElement(itemname);
System.out.println("Added "+itemname+" to ShopCart");
}

public void remove(String itemname) {


boolean result = items.removeElement(itemname);
if (result == false) {
System.out.println(itemname+" not in ShopCart");
}
else{
System.out.println("Removed "+itemname+" from S
hopCart");
}
}

public Vector showCart() {


return items;
}
public ShopCartEJB() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}
COMPILING AND DEPLOYING THE SESSION BEAN
Compiling the source files:
Follow the steps below:

1. Store the three files viz. ShopCart.java, ShopCartHome.java and ShopCartEJB.java in


the directory where you usually store your examples.

2. Compile the three files by using the javac comand

Directory> javac ShopCart.java


Directory> javac ShopCartHome.java
Directory> javac ShopCartEJB.java
This will generate three .class files in the same directory.
STARTING THE SERVER, DEPLOYTOOL AND CREATING THE SHOPCARTAPP.EAR FILE.

3. Start the J2EE Server by typing the following command at the prompt
C:> J2EE -verbose.

4. Start the deploytool by typing the following command a new command prompt after
changing to the directory containing the deploytool.bat file. This is in the bin folder within
your J2EE installation Directory.
path to installation directory\bin> deploytool

5. Open "File" and select "New Application". This opens a new window. Enter the
"Application Name" as "ShopCartApp". Browse and select the location of the file. Enter
the name for the file as "ShopCartApp.ear". This will add ShopApp to your local
"Applications window".

6. Confirm that ShopCartApp.ear file is added to the directory as well.

Note: The extension .ear stands for enterprise archive.


CREATING THE JAR FILE AND DEPLOYING THE APPLICATION

7. Click on the "File" Menu and select "New Enterprise Bean". This opens a
new Window "New Enterprise Bean Wizard". Click Next.

8. Enter the Display Name as "ShopCartEJB".

9. Press the "Add" button within "Contents".

10. Select the three .class files and say OK. Then press "Next".

11. Select classname as "ShopCartEJB", Home Interface as "ShopCartHome", Remote


Interface as "ShopCart". Enter the Display Name as "ShopCartDemo". Select bean type
as "Session" and "Stateful".

12. Skip "Environment Entries" and press "Next"

13. Skip "Enterprise Bean References" and press "Next"

14. Skip "Enterprise Resource References" and press "Next"

15. Skip "Security" and press "Next"

16. Skip "Transaction Management" and press "Next"

17. Press "Finish".

18. Select the "ShopCartApp" in "Local Application" of the deploytool. Go to the "JNDI
Names" tab and enter "MyShopCart" in the "JNDI Name" field. Highlight the row and
select "save" from the "File" Menu.

19. Go to the Tools Menu and select the "Deploy Application". Tick the Return Client jar and
enter the location where your files are stored. This will cause the ShopAppClient.ear file
to be placed within that directory.

20. Deployment will begin and when it is complete Press "OK".

21. If deployment was successful ShopCartApp will appear in the "Server Applications"
Panel.
THE "ShopCartClient" CLASS
The code is reproduced below:
// ShopCartClient.

javaimport java.util.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

public class ShopCartClient {

public static void main(String[] args) {


try {
Context initial = new InitialContext();
Object objref = initial.lookup("MyShopCart");

ShopCartHome home =
(ShopCartHome)PortableRemoteObject.narrow(objref,
ShopCartHome.class);

ShopCart shopCart = home.create("Thomas","123");

shopCart.add("trouser");
shopCart.add("shirt");
shopCart.add("socks");

Vector allitemList = new Vector();


allitemList = shopCart.showCart();

Enumeration enumer = allitemList.elements();


System.out.println("Items in Shop Cart are:");
while (enumer.hasMoreElements()) {
String itemname = (String)enumer.nextElement();
System.out.println(itemname);
}

shopCart.remove("trouser");
allitemList = shopCart.showCart();
enumer = allitemList.elements();
System.out.println("Items in Shop Cart now are:");
while (enumer.hasMoreElements()) {
String itemname = (String)enumer.nextElement();
System.out.println(itemname);
}

} catch (Exception ex) {


System.err.println("Caught an exception!");
ex.printStackTrace();
}
}
}

The class contains a main( ) method.

The client looks up the bean by its JNDI name which in this case is "MyShopCart". A reference to
the home interface of the bean is returned which is then explicitly type-cast into one of
ShopCartHome type.

Three items are added to the cart and the contents are displayed. Then one of the items is
removed and the contents displayed again.
COMPILING AND RUNNING THE CLIENT
Create the following bat file and run it
set J2EE_HOME=<J2EE installation directory>
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar
javac -classpath %CPATH% ShopCartClient.java

It sets the J2EE_HOME variable if it has not already been set and includes j2ee.jar into the
CLASSPATH variable. And then it compiles the ShopCartClient.java file.

Create this second bat file and run it

set J2EE_HOME=<J2EE installation directory>


set CPATH=.;%J2EE_HOME%\lib\j2ee.jar;ShopCartAppClient.jar
java -classpath "%CPATH%" ShopCartClient

The above commands actually run the Client code. Ensure that the J2EE Server is also running.

The output on the J2EE Server window reads as follows:

Added trouser to ShopCart


Added shirt to ShopCart
Added socks to ShopCart
Removed trouser from ShopCart

The output on the Client window reads as follows:

Items in Shop Cart are:


trouser
shirt
socks
Items in Shop Cart now are:
shirt
socks
ENTITY BEANS
Entity Beans represent data present in a database. Consider a bean which holds all the
information related to a customer "Thomas". Entity beans are persistent. Which means that they
are written to a database. This would also imply that the lifetime of the bean is limited to the
lifetime of the container/Server as it is in the case of Session beans. Since the bean is persistent
the crashing of the server will not affect it.
The same Entity bean instance can be shared between multiple clients since there may be more
than one client who wishes to access data related to the same customer "Thomas".

Entity beans use transactions to prevent concurrent access by multiple clients from corrupting the
values in the database.

An Entity bean class must extend the javax.ejb.EntityBean interface .

The additional requirements in an Entity bean as compared to a session bean are as follows:
1) Methods that support management of persistent state ( ejbLoad( ) and ejbStore( ) )
2) Finder methods
3) A Primary key class or an index. (In the EJB specification 1.1 if the primary key is an object of
String type then a separate class is not required).

Entity beans can be of two types :


1) Container Managed Persistence (CMP), and
2) Bean Managed Persistence (BMP).
The detailed differences between the two will be covered later.

I'll now explain why the combination of a session and entity bean is beneficial.

• It reduces the number of stubs that are required on the client side.

• It reduces network traffic and introduces load sharing.

• It also hides a lot of the business logic and methods.

Note : Support for entity beans by the EJB Server was not compulsory upto EJB 1.0 specification.
But with specification 1.1 this has been made binding.
ENTITY BEANS CHARACTERISTICS
Typical properties of an Entity bean are summarized below:
• Represents data present in a database and it is valid and "alive" till the data it represents
in the database is not removed. And conversely, if the bean is removed the data it
represents in the database is also removed. The bean will not be removed if the
container/Server crashes since it is persistent

• Permits multiple clients to share the bean.

• May have Finder methods in the Home interface which can be used to
search for beans.

• Has a primary key that is used to identify it uniquely.


ENTITY BEANS METHODS
As explained earlier there are several extra methods to be handled in the Bean Implementation
class. These are:
1) ejbFindByPrimaryKey
We have already dwelled on this method and will not repeat the explanation.

2) ejbPostCreate
This can be optionally implemented if additional initialization work is required to be carried out
and must take the same parameters as the corressponding ejbcreate( ) method.

3) ejbLoad
This method is called by the container to cause the bean instance to load/refresh it's state from
persistent storage.

4) ejbStore
This method is called by the container to cause the bean instance to write it's state to persistent
storage.

5) setEntityContext
This method is called by the container to set the EntityContext variable.

6) unsetEntityContext
This method is called by the container just before the entity bean is destroyed.

It is important to know the order of calling of methods:


1) The bean is first constructed.
2) The setEntityContext method is called.
3) The create method is called. (This creates a record in the database. Loading is not done in this
step.)
4) The ejbLoad method is called. (Loads the data from persistent storage into the bean).
CONTAINER AND BEAN MANAGED PERSISTENCE
In case of Container Managed Persistence the Container is responsible for transactions and the
Developer does not have to be concerned with the transaction details nor does he have to code
for the same. The container is aware of the fields present in the database and thus can do
insertions, deletions and updating. Codes for the Finder methods are automatically generated at
the time of deployment.
Bean Managed Transactions are more useful when there is a complex relationship or mapping
between the tables, data and the fields in the database. In such cases use of bean managed
persistence is difficult to avoid. The developer has to build the logic and code for database
transactions. The find methods in the home interface will also have to be explicitly coded for.
PRIMARY KEY
While developing an Entity bean it is essential that the EJB container must be provided with a
primary key class for the bean.
The primary key helps to,
1) uniquely identify the bean as well as the data in persistent storage.
2) load, update the bean's state from persistent storage.
3) behaves as a wrapper class around the primary key.
As we had mentioned, with the advent of newer specifications this is not compulsory for primary
keys of type java.lang.String.

Consider a primary key of a hypothetical type "Data" and of name "data" for the class
"DataStore". The primary key class in that case would look similar to this:

public class DataStorePK implements java.io.Serializable{


public Data data;
public DataStorePK(){
data=null;
}
public DataStorePK(Data data){
this.data=data;
}
}

Note that the class implements java.io.Serializable.

If the bean is of container managed persistence type then the following is also compulsory:
1) The class must be public.
2) Must have a default public constructor that takes no arguments.
3) All the data members must be public.
4) All the names of the data members of the class must match the names of the container
managed data members on the entity bean.
FINDER METHODS
Entity beans have finder methods which can be used by clients to find beans. For each find
method in the home interface there must be a corresponding ejbFind method in the bean
implementation class with matching signatures. The prefix of "find" is compulsory.
There are two return - types that the finder method can have.
1) Instance of the bean's remote interface or a collection of these object's
2) Enumeration. This is used if the method can return more than one reference. (With
specification 1.1 it is possible to return an object of Collection API as well).

For e.g. a method


Enumeration findByFirstName(String FirstName)
in the some interface must have a corresponding
Enumeration ejFindByFirstName(String FirstName)
in the bean implementation class.

There is one standard Finder method defined by the EJB Specification. This is the
findByPrimaryKey( ) method. It is the only required Finder method. Other FInder methods are
optional. The return type and the parameter passed must be of the bean's primary key type.

For e.g. a method


SocialSecurityNumber findByPrimaryKey(PrimaryKey key)
in the some interface must have a corresponding
SocialSecurityNumberPK ejbFindByPrimaryKey(PrimaryKey key)
in the bean implementation class.

Note that primary key objects are the return types of the ejbFind method.

All EJB Finder methods must be declared to throw the RemoteException and the
FinderException.
PASSIVATION AND ACTIVATION
Lets look at the process of passivation and activation with a few pictures.
Step 1 : When the bean is about to be passivated the ejbPassivate ( ) method is
called. The state of the bean is written to persistent storage.

Step 2 : The bean may then be returned to the bean pool.

Step 3 : When the bean (not necessarily the one which was passivated) has to be
activated again it is called from the pool and it's state restored from
persistent storage.
DEVELOPING A FIRST ENTITY BEAN
This module aims at showing you how a simple Entity Bean can be written, and then deployed.
We will also create a Client which will access the method of the bean. The bean used will access
a Cloudscape database for storage and retrieval of data.
The function of the bean is to get the information of a customer and store it into the database and
then display the same through other methods.

There are four classes. These are

• Customer.java

• CustomerHome.java

• CustomerEJB.java

• CustomerClient.java.

Customer.java is the remote interface. CustomerHome is the Home interface. CustomerEJB is


the EJB Object class which provides the implementation for the Remote Interface. And
CustomerClient.java as the name suggests is the client class which makes a request to server for
the bean.

Make a mental note that this is a container managed bean. This means that the transactions are
taken care of by the Container. It is also possible to have bean managed transactions. Both of
these types and the differences between them will be taught in a later lesson.

Let us now put all the pieces together.


THE "Customer" INTERFACE
The following is the code of the Customer Bean's Home Interface. The methods defined include
those required to retrieve the First Name, Last Name, Age and Sex of the Customer for a
particular identity number, in this case id, which is the primary key.
// Customer.java

import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Customer extends EJBObject {

public String getFirstname( ) throws RemoteException;

public String getLastname( ) throws RemoteException;

public int getAge( ) throws RemoteException;

public String getSex( ) throws RemoteException;


}
THE "CustomerHome" INTERFACE
This is the Home interface of the CustomerEJB Bean. As expected it extends the javax.ejb.EJBHome interface. It def
create( ) method which returns a reference to a Multiplier bean instance which was created.
The method can throw a RemoteException or a CreateException.

In addition there are two finder methods included. One searches for a bean based on a particular primary key id. The s
used to obtain a list of all the customers of a particular gender.

// CustomerHome.java

import java.util.Collection;
import java.rmi.RemoteException;
import javax.ejb.*;

public interface CustomerHome extends EJBHome {


public Customer create(String id, String Firstname, String Lastname, int Age, String S
throws RemoteException, CreateException;

public Customer findByPrimaryKey(String id) throws FinderException, RemoteException;

public Collection findBySex(String Sex)throws FinderException, RemoteException;

}
THE "CustomerEJB" CLASS
It implements the javax.ejb.Entity Bean interface since it is an Entity Bean.
// CustomerEJB.java

import java.util.*;
import javax.ejb.*;

public class CustomerEJB implements EntityBean {

public String id;


public String Firstname;
public String Lastname;
public int Age;
public String Sex;

private EntityContext context;

public String getFirstname() {


return Firstname;
}

public String getLastname() {


return Lastname;
}

public int getAge() {


return Age;
}

public String getSex() {


return Sex;
}

public String ejbCreate(String id, String Firstname, String Lastname, int Age, String
throws CreateException {
if (id == null) {
throw new CreateException("id cannot be null.");
}
this.id = id;
this.Firstname = Firstname;
this.Lastname = Lastname;
this.Age = Age;
this.Sex = Sex;
return null;
}

public void setEntityContext(EntityContext context) {


this.context = context;
}

public void ejbActivate() {


id = (String)context.getPrimaryKey();
}

public void ejbPassivate() {


id = null;
Firstname = null;
Lastname = null;
Sex = null;
}

public void ejbRemove() { }

public void ejbLoad() { }

public void ejbStore() { }

public void unsetEntityContext() { }

public void ejbPostCreate(String id, String Firs


tname, String Lastname, int Age, String
}

}
EXPLANATION OF METHODS IN THE CustomerEJB CLASS
Carefully note all the methods in the bean class. There are four methods used to return the
values of First Name, Last Name, Age and Sex.
There is an ejbCreate( ) method which is responsible for getting a reference to a bean instance.
As you can see, a record is also created in the database using values passed as parameters to
the method. There can be more than one create methods provided its signature is different. For
each create( ) method there can be a corresponding ejbPostCtreate( ) with matching signatures.
The ejbPostCreate( ) method is generally used to give an opportunity to do any additional
initialization prior to allowing the bean to service a request.

The rest of the methods are Callback methods which are used to inform the bean class when
there is any change in the state of the bean. The EJBStore( ) and EJBLoad( ) is used when the
bean is about to be written into persistent storage and when it is about to be restored from it,
respectively. In the given example there is no implementation. This is because this is a container
managed example. The container is responsible for handling it. However, in case of bean
managed transactions this has to be taken care of by code in these methods. When the container
is about to remove the bean it invokes the EJBStore( ) method of the bean instance which gives
the bean instance a chance to transfer it's data to persistent storage.

The ejbPassivate( ) and ejbActivate( ) methods are used in case of stateful Session Beans to
save it's state into persistent storage. But note that this is held relative to it's EJB Object.

The EntityContext provides information to the bean instance about the container, its environment,
the client who is accessing it.
STEPS TO DEPLOYING THE ENTITY BEAN
Let us look at how we can deploy this bean in the J2EE Server.
Follow the steps below:

1. Store the three files viz. Customer.java, CustomerHome.java and CustomerEJB.java in


the directory where you usually store your examples.

2. Compile the three files by using the javac comand

Directory> javac Customer.java


Directory> javac CustomerHome.java
Directory> javac CustomerEJB.java
This will generate three .class files in the same directory.
STARTING THE SERVER, DEPLOYTOOL AND CREATING THE CUSTOMER.EAR FILE

3. Start the Cloudscape database by typing the following command at the prompt.

C:> cloudscape -start

Start the J2EE Server by typing the following command at the prompt.

C:> J2EE -verbose.

4. Start the deploytool by typing the following command a new command prompt after
changing to the directory containing the deploytool.bat file. This is in the bin folder within
your J2EE installation Directory.
path to installation directory\bin> deploytool

5. Open "File" and select "New Application". This opens a new window. Enter the
"Application Name" as "CustomerApp". Browse and select the location of the file. Enter
the name for the file as "CustomerApp.ear". This will add CustomerApp to your local
"Applications window".

6. Confirm that CustomerApp.ear file is added to the directory as well.


CREATING THE JAR FILE AND DEPLOYING THE APPLICATION
7. Click on the "File" Menu and select "New Enterprise Bean". This opens a
new Window "New Enterprise Bean Wizard". Click Next.

This opens the Enterprise Bean Wizard Window


8. Enter the Display Name as "CustomerEJB".

9. Press the "Add" button within "Contents".

10. Select the three .class files and say OK. Then press "Next".

11. Select classname as "CustomerEJB", Home Interface as "CustomerHome", Remote


Interface as "Customer". Enter the Display Name as "CustomerDemo". Select bean type
as "Entity". Press "Next"

12. In the "Entity Settings" window select "Container Managed Persistence". Check all five
boxes which are the fields of the database. Enter primary key class as java.lang.String
and the Primary Key Fieldname as id. Press "Next".

13. Skip "Environment Entries" and press "Next".

14. Skip "Enterprise Bean References" and press "Next"

15. Skip "Enterprise Resource References" and press "Next"

16. Skip "Security" and press "Next"

17. In the "Transaction Management" window change Transaction Type of getFirstname,


getLastname, getAge and getSex to required and press "Next"

18. Press "Finish".

19. Double-click "CustomerApp" in the local Application panel. Double-click "CustomerEJB".


Select "CustomerDemo".

20. Select the Entity tab and click on "Deployment Settings".

21. Enter the database JNDI name as jdbc/Cloudscape.

22. Press "Generate SQL now".

23. In the SQL Generator window press OK.

24. You now have to provide the where clause for the FindbySex( ) method.

25. Add "WHERE "Sex" = ?1" to the incomplete SQL statement indicated by FindbySex( )
method.

26. Press "OK".


27. Select the "CustomerApp" in "Local Application" of the deploytool. Go to the "JNDI
Names" tab and enter "MyCustomer" in the "JNDI Name" field. Highlight the row and
select "save" from the "File" Menu.

28. Go to the Tools Menu and select the "Deploy Application".

29. Deployment will begin and when it is complete Press "OK". Tick the Return Client jar and
enter the location where your files are stored. This will cause the CustomerAppClient.ear
file to be placed within that directory.

30. If deployment was successful CustomerApp will appear in the "Server Applications"
Panel.

Next we will look at the Client class which will access the bean.
THE "CustomerClient" CODE
The expanation is similar to the earlier client code we had described about the MultiplierClient
class. But note the difference in the create methods used to create records. It creates three
records. Prints out the name of the person with id value of 3 and also prints the values of all
female customers.
// CustomerClient.java

import java.util.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

public class CustomerClient {

public static void main(String[] args) {


try {
Context initial = new InitialContext();
Object objref = initial.lookup("MyCustomer");
CustomerHome home =

(CustomerHome)PortableRemoteObject.narrow(objref,CustomerHome.class);
Customer Temp = home.create("1", "Thomas", "Thomas", 26, "Male");
Temp = home.create("2", "Andrew", "Peter", 42, "Male");
Temp = home.create("3", "Igor", "Valentine", 29, "Male");
Temp = home.create("4", "Suzie", "Limor", 23, "Female");
Customer Unknown = home.findByPrimaryKey("3");
System.out.println(Unknown.getFirstname()+" "
+Unknown.getLastname()+":
"+Unknown.getAge()+": " +Unknown.getSex());
Collection c = home.findBySex("Female");
Iterator i = c.iterator();
while (i.hasNext()) {
Customer temp = (Customer)i.next();
String Id = (String)temp.getPrimaryKey();
System.out.println(Id + ": " + temp.getFirstname());
}
} catch (Exception ex) {
System.err.println("Caught an exception." );
ex.printStackTrace();
}
}
}

The output will be as follows

Igor Valentine: 23 : Male


4: Suzie
TRANSACTIONS
A Transaction is basically a series of operations which are committed if all the operations
succeed or rollbacked if even one of it fails. So, all the units within the same transaction succeed
or fail as a whole.
Consider for example the process of booking a ticket for a football game. Consider a booking
bean, which does the function of checking whether there is a free seat or not. A second bean
handles the financial transaction of payment by the customer.

Two things must be disallowed.

1. It shouldn't happen that the seat is not available but that the amount is deducted from the
person's account.

2. Nor should the person be given a free ticket i.e. he gets the ticket but is not charged the
amount.

Either, both take place or none. The process must be atomic.

There are several attributes defined, which determine how transactions are to be managed by the
container. These attributes can be defined on the bean as a whole, which will make it binding on
all methods or it can be made exclusively for each method. When we do the former it is much
simpler. However, the latter allows for greater control at the method level. The most commonly
used attribute types are TX_REQUIRED and TX_BEAN_MANAGED.

TX_REQUIRED means that the bean method must be invoked within the scope of a transaction.
If the client is already in a transaction of it's own, the transaction context is passed on to the bean
in it's EJBContext.

TX_BEAN_MANAGED is specified when the bean is made responsible for transactions.

There are four isolation levels defined. The most commonly used value for this is
TRANSACTION_SERIALIZABLE. This is the most restrictive isolation level and is the safest. This
allows only one transaction to read or write a database at a time. It would however mean a long
queue for all other transactions wishing to read or write to the database. This however prevents
any possibility of a dirty read. A dirty read is said to occur when one transaction reads from a
database which is then changed by another which would mean that the data held by the former
transaction is invalid.
HANDLES
A Handle is a serializable reference to the EJB Object. By using the technique of serialization the
client can save the Handle object and later on deserialize it to once again obtain a reference to
the the same EJB Object. The Handle has all the information to obtain the remote reference to a
particular EJB Object.
A Handle is different from a primary key in the following ways.

1) While trying to obtain a reference using the primary key it is necessary to have a reference to
the EJB home and thus requires three steps.
But in the case of a Handle only a single method call is sufficient.
Handle.getEJBObject();

2) A Handle can be used for both entity as well as session beans unlike a primary key is valid
only for the former.
CONCLUSION
This concludes the topic of Enterprise JavaBeans. I hope it has given you an overview of Enterprise JavaBeans. Seve
advanced topics such as handles, transactions were also discussed. Four examples were also covered in detail. You s
now be able to design basic EJB objects and deploy them.
Thank You.

Das könnte Ihnen auch gefallen