New York
University
Computer
Science Department
Courant
Institute of Mathematical Sciences
Session 11:
Using Enterprise JavaBeans
Course Title: Extreme Java Course Number: g22.3033-007
Instructor: Jean-Claude Franchitti
Session: 11
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."
Save the
DemoBean source code 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.
The source code for the DemoBean
EJB follows:
/**
* 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.
The
source code for the DemoBean Enterprise JavaBeans DemoBean.java follows:
/**
* 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.
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/startTengah.sh script to include the Demo.jar file.
/export/weblogic/startTengah.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/DemoBeanDD.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/startTengah.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
/**
* 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...