New York University
Computer
Science Department
Courant
Institute of Mathematical Sciences
Building a
Stateless Session Bean
Course Title: Application Servers Course Number: g22.3033-011
Instructor: Jean-Claude Franchitti Session: 7
Table of Contents
·
How
to Build Your First Stateless Session Bean
Step 1: Install an Enterprise JavaBeans Server
Step 2: Specify
the Enterprise JavaBeans Remote Interface
Step 3: Specify
the Home Interface
Step 4: Write
the Enterprise JavaBean Class
Step 5: Create
the ejb-jar File
Step 6: Deploy
the DemoBean Enterprise JavaBeans
Step 7: Write
the Enterprise JavaBean Client
Step 8: Run the
Client
·
Summary
About this Tutorial
The intention of this tutorial is to demonstrate how
easy it is to build server-side Java components using the Enterprise JavaBeans
component model. In fact, ease-of-use and ease-of-programming are key. It is
designed to enhance your understanding of the Enterprise JavaBeans
Specification, and the Enterprise JavaBeans model by providing concrete
examples and step-by-step guidelines for building and using Enterprise
JavaBeans applications.
This tutorial shows you how to program Enterprise
JavaBeans, and how to install, or deploy, them in an Enterprise
JavaBeans container. Note: in Enterprise JavaBeans terminology the installation
process is called deployment. The Enterprise JavaBeans Container is
provided by the Enterprise JavaBeans server vendor, so is not something the
programmer has to worry too much about.
By following the eight steps, and working through
the examples, you will become familiar with the fundamental pieces of the
Enterprise JavaBeans model, and create the Enterprise JavaBeans version of the
"Hello World" program.
To get the most out of this tutorial you need to be
familiar with at least the basic concepts of the Enterprise JavaBeans
programming model. Programmers who are not familiar with Enterprise JavaBeans
should refer to the Java Tutorial, and the
handout "The Enterprise JavaBeansTM Server Component Model for
the JavaTM Platform."
About the Example
The example introduces a complete stateless session
enterprise JavaBean with source code for all the components. It is functionally
equivalent to the perennial "Hello World" program. It is the simplest
of all enterprise beans to write, and demonstrates the Enterprise JavaBeans
model with minimum complexity.

The example is built
assuming access to the BEA Weblogic Enterprise JavaBeans server, which is
mainly for convenience as an evaluation version of this server, and is
available on the Web, (see Step 1 for BEA Weblogic download and installation
instructions). The code for the bean should work in any Enterprise
JavaBeans-compliant container or server. The only changes required should be in
the deployment process and perhaps the client code. The diagram below describes
the architecture of the DemoBean example and its client program.
Step 1: Installing an Enterprise JavaBeans Server
Enterprise JavaBeans components run inside
Enterprise JavaBeans containers, which are supplied by Enterprise JavaBeans
server vendors. The instructions below will assist in downloading and
installing a BEA Weblogic server in which the DemoBean will run.
Note: the installation instructions shown here
are for Sun Solaris, but the process is similar for Windows NT.
http://www.weblogic.com/licbeta.html
http://www.sun.com/solaris/java
Add
weblogic/classes and weblogic/lib/weblogicaux.jar to your Java CLASSPATH. Make sure you have "." or your
current directory in the CLASSPATH as well.
Add
weblogic/lib/solaris to your
LD_LIBRARY_PATH
Set
the system password property, weblogic.password.system
After
following the steps in this tutorial to build and deploy the example bean,
check that the Enterprise JavaBeans bean has been deployed correctly, either by
checking the server command-line window, or by opening the Console and
examining "EJB" under the "Distributed Objects"; you should
see DemoBean
deployed, and you can monitor its activity.
Step 2: Specifying the Enterprise JavaBeansTM
Remote Interface
In this step you will create the Enterprise
JavaBeans remote interface.
·
Read the explanation below.
·
Save the code example to a file as indicated.
The remote interface is the client's view of the
Enterprise JavaBeans, and the task of the Enterprise JavaBeans developer is to
declare this interface using JavaTM RMI syntax. It is the
responsibility of the Enterprise JavaBeans' container tools provider to
generate the code of this interface.
Note: There are limitations on what can be
specified in this interface. For a full list, see the Enterprise JavaBeans
Specification, Section 16. It is important that, all objects used,
the parameters, return values, and exceptions are valid types in the "Java
to IDL Mapping Specification."
For the simple DemoBean here is the remote
interface source. Save this to a file named Demo.java.
/**
* Demo -- this is the "remote" interface of
* our enterprise JavaBean, it
* defines only one simple method called
* demoSelect(). As this is meant to be
* the simplest of examples demoSelect()
* never goes to a database, it just
* returns a string
*
* Note: The implementation of this interface is
* provided by the container tools
* but the demoSelect() method and any
* other methods in this interface
* will need to have equivalent
* implementations in the demobean.java
* which is supplied by the bean writer
* ..i.e., you!
*/
package ejb.demo;
import
java.rmi.RemoteException;
import java.rmi.Remote;
import javax.ejb.*;
public interface Demo
extends EJBObject, Remote {
// NB this simple example does not even do a
// lookup in the database
public String demoSelect() throws RemoteException;
}
Step 3: Specifying the Home Interface
The
home interface for a session bean provides the mechanism by which the container
creates new session beans on behalf of the client. The home interface, just
like the remote interface, is declared by the bean developer in RMI syntax, and
again, is implemented by the container provider's tools. There is little-to-no
coding to be done by the programmer--it is really just declarative work at this
point.
Here
is the source code for the DemoBean EJB:
/**
* DemoHome.java - This is the Home interface it must
* extend javax.ejb.EJBHome and define one or more
* create() methods for the bean.
*
* Note: The implementation of this interface is
* generated by the container tools.
*/
package ejb.demo;
import javax.ejb.*;
import java.rmi.Remote;
import
java.rmi.RemoteException;
import java.util.*;
/**
* This interface is extremely simple it declares only
* one create method.
*/
public interface DemoHome
extends EJBHome {
public Demo create() throws CreateException,
RemoteException;
}
Step 4: Writing the Enterprise JavaBeanTM Class
This step shows you how to code of the application
(business logic) is done. Up until now, you have declared interfaces that the
container tools will generate code for, but here is where the functionality of
the JavaBean is coded.
One important thing to notice about the bean
implementation, is just how little code you have to author. Most of this code
is simply implementing methods from the Enterprise JavaBeans specification. It
is easy to envisage templates and tools that do most of the implementation work
for you. This is very comparable to the way tools have evolved for the GUI
beans environment.
Here is the source code for the DemoBean Enterprise JavaBeans DemoBean.java:
/**
* DemoBean -- This is implemented by the EnterPrise
* Bean author This class must extend
* javax.ejb.SessionBean and implement
* the methods in this interface as well as providing
* the implementation of the business methods.
*
*/
package ejb.demo;
import javax.ejb.*;
import java.io.Serializable;
import java.util.*;
import java.rmi.*;
public class DemoBean
implements SessionBean {
static final boolean verbose = true;
private transient SessionContext ctx;
private transient Properties props;
// Implement the methods in the SessionBean
// interface
public void ejbActivate() {
if (verbose)
System.out.println("ejbActivate called");
}
public void ejbRemove() {
if (verbose)
System.out.println("ejbRemove called");
}
public void ejbPassivate() {
if (verbose)
System.out.println("ejbPassivate called");
}
/**
* Sets the session context.
*
* @param SessionContext
*/
public void setSessionContext(SessionContext ctx) {
if (verbose)
System.out.println("setSessionContext called");
this.ctx = ctx;
props = ctx.getEnvironment();
}
/**
* This method corresponds to the create method in
* the home interface DemoHome.java.
* The parameter sets of the two methods are
* identical. When the client calls
* DemoHome.create(), the container allocates an
* instance of the EJBean and calls ejbCreate().
*/
public void ejbCreate () {
if (verbose)
System.out.println("ejbCreate called");
}
/**
* **** HERE IS THE BUSINESS LOGIC *****
* Do the demoSelect() but don't even go to
* the database in this eg but instead just
* return a String.
* The really BIG thing to notice here is that
* this is the only code we have invented at all
* the rest of the code has been declarations
* or simply implementing methods which are
* part of the EJB interfaces and in this example
* are not even used.
*/
public String demoSelect()
throws RemoteException
{
return("hello world");
}
}
Step 5: Creating the ejb-jar File
One
of the big advantages of Enterprise JavaBeans is the ability to package and
distribute server-side logic in the same portable fashion as GUI components. In
this step the source files from the preceeding steps are compiled and then
packaged into an ejb-jar file. By completing the
four steps below you will produce the Demo.jar ejb-jar file, which will then be
ready for deployment, or installation, into the Enterprise JavaBeans Container.
1. Compile the .java Files
Run
javac on the files you have just
created, that is, the home and remote interfaces, and the Enterprise JavaBeans
bean itself.
javac ejb/demo/DemoHome.java
javac ejb/demo/Demo.java
javac ejb/demo/DemoBean.java
2. Create the Deployment Descriptor
Note: Deployment is the Enterprise
JavaBeans term for installing the Enterprise JavaBeans components into an
Enterprise JavaBeans container.
The role of the deployment descriptor is to allow
the bean deployer to customize many of the
properties of the bean prior to deployment. The deployment descriptor is described in
the Enterprise JavaBeans Specification (section 15.2) as an instance of either javax.ejb.deployment.SessionDescriptor or
javax.ejb.deployment.EntityDescriptor. In the DemoBean example,
it is an instance of the javax.ejb.deployment.SessionDescriptor. Below is an example of the
text file input to WebLogic's utilities that generate the serialized instance
of this deployment descriptor.
Note that the methodology for creating the deployment descriptor is not
specified, so the tools used to generate and deploy Enterprise JavaBeans may look
and feel very different from each other, without affecting the cross-platform
deployment abilities of the beans themselves.
The example below continues with creating the DeploymentDescriptor with the WebLogic tools.
The BEA Weblogic server implementation offers both command line and GUI
deployment tools. So to deploy the Enterprise JavaBean using the command line
tools, issue the following commands:
java weblogic.ejb.utils.DDCreator -dir ejb/demo ejb/demo/DeploymentDescriptor.txt
This will create DemoBeanDD.ser in the ejb/demo directory.
An example DeploymentDescriptor.txt textfile
for input to the BEA Weblogic tools (source):
(SessionDescriptor
; This file must start with
SessionDescriptor or
; EntityDescriptor
; Indicate the name which
the bean will be bound
; into the JNDI name as
beanHomeName demo.DemoHome
; The enterprise Java Bean
class (see step 4)
enterpriseBeanClassName ejb.demo.DemoBean
homeInterfaceClassName ejb.demo.DemoHome
; The home interface
implemented by a class
; generated by the container
provided tools
; see step 3
remoteInterfaceClassName ejb.demo.Demo
; See step 2
isReentrant false
; Always false for session
beans
stateManagementType STATELESS_SESSION
; Either STATELESS_SESSION
or STATEFUL_SESSION.
; DemoBean is a stateless
session bean
sessionTimeout 5
; seconds
(controlDescriptors
; This section decides the
run-time properties when
; a method is called. The
DEFAULT sub-section applies
; to all methods, but can be
overridden on a per-method
; basis, similar to the
"accessControlEntries" above.
(DEFAULT
isolationLevel
TRANSACTION_SERIALIZABLE
transactionAttribute
TX_REQUIRED
runAsMode
CLIENT_IDENTITY
)
; end isolationLevel
)
; end controlDescriptors
(environmentProperties
maxBeansInFreePool
100
)
; end environmentProperties
)
; end SessionDescriptor
Note: This example is for the BEA Weblogic server
which uses the semi-colon (;) to comment out lines.
3. Create The Manifest
The manifest is automatically generated by the jar utility, but will take a
template, so create a text file (for example, ejb/demo/manifest.txt) with the contents below.
Refer to the next section on packaging the bean to see how this text file is
used.
For a description of the manifest file, see the Enterprise JavaBeans
Specification, Section 15.3.
Name: ejb/demo/DemoBeanDD.ser
Enterprise-Bean: True
4. Make Sure You Have all the pieces
Here are the pieces the Enterprise JavaBeans
developer and provider need to supply to create a valid ejb-jar file, that is, the
Enterprise JavaBeans bean:
·
The enterprise bean class + any other classes the bean
depends upon (Step 4).
·
The enterprise bean's remote interface (Step 2).
·
The enterprise bean's home interface (Step 3).
·
A deployment descriptor (see above).
·
An instance of java.util.Properties, if
needed by the bean.
·
A manifest file that identifies the deployment descriptors
in the ejb-jar file.
See the Enterprise JavaBeans Specification, section
16, for more details.
The Enterprise JavaBeans bean provider is
responsible for putting all of these classes into the ejb-jar file, but it is expected
that most of the container and server providers will provide tools for doing
this packaging and assembly.
The Manifest
The manifest is automatically generated by the jar utility, but will take a
template, so create a text file (for example, ejb/demo/manifest.txt) with the contents below.
Refer to the next section on packaging the bean to see how this text file is
used.
For a description of the manifest file, see the Enterprise JavaBeans
Specification, Section 15.3.
Name: ejb/demo/DemoBeanDD.ser
Enterprise-Bean: True
5. Create the ejb-jar file
For the example you simply jar all the pieces
together to make a jar file called Demo.jar. It is expected that future
tools will make the packaging and the generation of the ejb-jar file much easier. You can
imagine a GUI wizard leading you through and checking dependencies here very
easily.
To create the ejb-jar file Demo.jar for the example, you can
assume the pieces of the jar file are all under a directory called ejb. You simply create a jar
file of this directory structure.
Notes: Use the m flag to jar and ejb/demo/manifest.txt as a template for the
manifest. It is not necessary to put the manifest.txt into the jar file.
jar
cvfm Demo.jar ejb/demo/manifest.txt ejb/demo/*.class \
ejb/demo/*.ser
Inspecting the Demo.jar should produce output
similar to:
jar tf Demo.jar
META-INF/MANIFEST.MF
ejb/demo/Demo.class
ejb/demo/DemoBean.class
ejb/demo/DemoHome.class
ejb/demo/DemoBeanDD.ser
So as you can see, there is nothing too special
about the ejb-jar file.
Step 6: Deploying the DemoBean Enterprise JavaBean
In this step the DemoBean Enterprise JavaBean is
installed, or deployed, into an Enterprise JavaBeans container. It is important
to note that each of the server vendors will have specific and increasingly
sophisticated tools to enable this installation.
Follow the instructions below to install the
DemoBean into the BEA Weblogic server, which you installed in Step 1.
BEA WebLogic Deployment
In the current release of the Weblogic server from
BEA WebLogic, deployment of the Enterprise JavaBeans bean means "putting
the bean classes where the Weblogic server can find them." This is not a
difficult thing to do, but it is not very elegant either, and it is expected
that there will be tools to simplify this step, as well as make what is
happening more obvious.
Note: This example assumes the Weblogic server is
installed in the /export directory.
1. Generate the implementations
This step creates the implementations of the
interfaces specified earlier, and the supporting BEA WebLogic-specific classes
for the DemoBean. Notice that they are not
packaged with your bean. The classes that are generated are, for example, the
home and remote interfaces, as well as the classes required for supporting the
communications protocols. The fact that these classes are generated at
deployment time, and not written by the bean provider (programmer) is a major
part of what enables Enterprise JavaBeans to be protocol-neutral.
Note: Assume that the Weblogic server has been
installed into the /export directory. You will need to
modify the destination directory (that is, -d parameter below) if it is
installed somewhere else.
To generate the implementations for the DemoBean using the BEA WebLogic
tools, use:
java
weblogic.ejbc -d /export/weblogic/classes ejb/demo/DemoBeanDD.ser
This
utility creates classes with names similar to those below and puts them under
the
/export/weblogic/classes directory.
ejb/demo/DemoBeanEOImpl.class
ejb/demo/DemoBeanHomeImpl.class
ejb/demo/Skel5k5x705r2x671nd1i1vy2v524ua5y.class
ejb/demo/Skel5q585f5sfzo601q4e725b233m5140.class
ejb/demo/Stub5k5x705r2x671nd1i1vy2v524ua5y.class
ejb/demo/Stub5q585f5sfzo601q4e725b233m5140.class
2. Put the Demo.jar into CLASSPATH of Weblogic server
There are several ways to do this, but the simplest
is to put the Demo.jar file into the /export/weblogic/classes directory, then edit the
/export/weblogic/startWebLogic.sh script to include the Demo.jar file.
/export/weblogic/startWebLogic.sh
#!/bin/sh
#
# Shell script to manually start Weblogic
# Server on UNIX systems
CLASSPATH=$CLASSPATH:/export/weblogic/classes/Demo.jar
echo $CLASSPATH
java -ms16m -mx16m -verbosegc weblogic.Server
3. Edit the weblogic.properties file
Include the loading and startup instructions for the
new Enterprise JavaBeans.
/export/weblogic/weblogic.properties
# # # # # # # # # # # # # # # # # # # # # # # # # #
# Weblogic Enterprise JavaBeans DEMO PROPERTIES
# -------------------------------------------------
# Uncomment the appropriate lines below and modify
# DBMS-related info and paths to match your particular
# installation.
#
# Deploys the Enterprise JavaBean examples.
Uncomment to use:
weblogic.ejb.deploy=\
/export/weblogic/classes/beanManaged.jar,\
/export/weblogic/classes/containerManaged.jar,\
/export/weblogic/classes/statefulSession.jar,\
/export/weblogic/classes/demo.jar
#
# weblogic.properties file continues below...
#
4. Stop and restart the Weblogic Server
You can use either the BEA Weblogic tools to stop
and restart the Weblogic server or in a environment simply kill the main
Weblogic process, and use the /expot/weblogic/startWebLogic.sh script to restart. For
details, see the BEA
Weblogic tools documentation.
Step 7:
Writing the Enterprise JavaBean Client
If you have sucessfully completed Steps 1 through 6,
the DemoBean should now be deployed into the Enterprise JavaBeans container and
ready to accept a client call to any of the methods specified in the remote
interface.
Overview of Writing the Client
Writing the client is another place in the process
where you get to write some code, apart from the Enterprise JavaBeans bean
business logic itself. The client to an Enterprise JavaBeans bean can be a
variety of things: for example, a servlet, an applet, or perhaps a C/C++
program. The example DemoClient.java below is the client to the DemoBean Enterprise JavaBean,
created in the previous steps. The important things to note about this program
are:
·
Establish the JNDI initial Context.
·
Locate the Home interface of the Enterprise JavaBean using
JNDI.
·
Use the Home interface instruct the Container to create an
instance of the Enterprise JavaBean.
·
The use of the remote interface to instruct the container
to execute the methods of the Enterprise JavaBeans bean.
Another thing to note is that as you deploy the bean
in different containers/servers, there will need to be differing versions of
the client code. The differences in client code are not expected to be major,
but there might be issues, such as the correct strings for getting the initial
connection. For example, consider the following code, which sets up the
Properties object for BEA WebLogic to retrieve the JNDI initialContext object. It may differ from
the Oracle Properties string to get the initialContext object.
p.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.T3InitialContextFactory");
There are a variety of other small issues that might
require some tuning and recompilation of the client code, but these are not
expected to require huge amounts of work.
The sample Enterprise JavaBeans client below
demontrates how to locate an Enterprise JavaBean and to invoke its remote
methods.
DemoClient.java (source)
/**
* DemoClient -- demonstrates using a minimal
* Java application to talk to the DemoBean
* stateless session bean
*/
package ejb.demo;
import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import java.util.Properties;
/**
* DemoClient demonstrates using a minimal stateless
* session bean.
* Remember view session beans as an extension of your
* client running in the server.
*/
public class DemoClient {
public static void main(String[] args) {
System.out.println("\nBegin DemoClient...\n");
parseArgs(args);
try {
// Create A DemoBean object, in the server
// Note: the name of the class corresponds to the
// JNDI property declared in the
// DeploymentDescriptor
// From DeploymentDescriptor ...
// beanHomeName demo.DemoHome
Context ctx = getInitialContext();
DemoHome dhome = (DemoHome)
ctx.lookup("demo.DemoHome");
// Now you have a reference to the DemoHome object
// factory use it to ask the container to creat an
// instance of the Demo bean
System.out.println("Creating Demo\n");
Demo demo = dhome.create();
// Here is the call that executes the method on the
// server side object
System.out.println("The result is "
+ demo.demoSelect());
}
catch (Exception e) {
System.out.println(" => Error <=");
e.printStackTrace();
}
System.out.println("\nEnd DemoClient...\n");
}
static void parseArgs(String args[]) {
if ((args == null) || (args.length == 0))
return;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-url"))
url = args[++i];
else if (args[i].equals("-user"))
user = args[++i];
else if (args[i].equals("-password"))
password = args[++i];
}
}
static String user = null;
static String password = null;
static String url = "t3://localhost:7001";
/**
* Gets an initial context.
*
* @return Context
* @exception java.lang.Exception if there is
* an error in getting a Context
*/
static public Context getInitialContext()
throws Exception {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.T3InitialContextFactory");
p.put(Context.PROVIDER_URL, url);
if (user != null) {
System.out.println ("user: " + user);
p.put(Context.SECURITY_PRINCIPAL, user);
if (password == null)
password = "";
p.put(Context.SECURITY_CREDENTIALS, password);
}
return new InitialContext(p);
}
}
Step 8: Compiling and Running the Client
All that remains to do is to compile and run the
Client program to ensure that the Enterprise JavaBeans, installed in the
servers, function correctly.
Compiling and running the client are identical for
all platforms, as should be the results from running the client.
1. Compile the client
javac
ejb/demo/DemoClient.java
2. Run the client
The "Hello World" string comes from the
DemoSelect() method of the Enterprise JavaBeans. Running the client should give
the following messages:
java
ejb.demo.DemoClient <cr>
Begin
DemoClient...
Creating
Demo
The
result is hello world
End
DemoClient...
Summary
You now have the DemoBean example working and you
have sucessfully run the client. If so, then you should now also have some feel
for the required parts of an Enterprise JavaBeans application, and how easy it
is to create real distributed multitier applications.
Basic Recipe
An important thing to notice is that while the
design and implementation of a "real" application might take a lot
more time, and involve far more complex logic to model the business, the recipe
is basically the same. The Java programmer follows the steps of specifying the
interfaces, remote, home, and so on, and then writing the logic in the bean, as
per the example recipe.
What You Didn't Do
In Enterprise Java beans much of the strength of the
model comes from what the programmer does not have to do, for instance Java
programmers no longer have to learn CORBA IDL, nor do they have to handle
multithreading issues. Indeed explicit creation of threads by the Enterprise
JavaBeans programmer is illegal in any Enterprise JavaBeans-compliant
container/server--this is the function of the server/container vendor. Other
things the Enterprise JavaBeans programmer does not have to code include:
security issues (these are declared in the DeploymentDescriptor), anything to
do with the underlying protocol, and anything that is platform-specific.
Next Steps
While simple examples are good to learn on, they can
also be annoying in what they don't cover. Specifically not covered in this
example is any type of database access. Hence security and transactional issues
are well highlighted, although as stated above there is little application
programming to be done for these. Also in both stateful-session beans, and
entity beans there is a little more work to do to utilise the "state"
kept on the server, and this is not highlighted.
One final point is that sophisticated tools for
Enterprise JavaBeans development are on their way from many of Sun's partners,
and much of the work done by hand in creating and declaring of interfaces and
so on, will become much simpler, for example, as simple as clicking a button!
In Conclusion
It is hoped this introduction has helped you to see
the strengths of the Enterprise JavaBeans model, and whether you are a seasoned
CORBA, Perl, or even VB programmer, it is hoped you will start to see just how
easy and powerful Enterprise JavaBeans can be!