0% found this document useful (0 votes)
76 views

Writing Enterprise Applications With J2SE & J2EE

This document introduces how to write a simple thin-client multitiered enterprise application using the Java 2 Enterprise Edition (J2EE) Software Development Kit (SDK). It provides an example application using a session bean and servlet. It also describes the necessary J2EE application components, compiling the code, deploying the application, and running it.

Uploaded by

Mahesh
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
76 views

Writing Enterprise Applications With J2SE & J2EE

This document introduces how to write a simple thin-client multitiered enterprise application using the Java 2 Enterprise Edition (J2EE) Software Development Kit (SDK). It provides an example application using a session bean and servlet. It also describes the necessary J2EE application components, compiling the code, deploying the application, and running it.

Uploaded by

Mahesh
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 120

APRIL 18, 2000

Writing Enterprise Applications with


Java 2 SDK, Enterprise Edition

by Monica Pawlan
APRIL 18, 2000

copyright  1995-99 Sun Microsystems, Inc.

As used in this document, the terms “Java virtual machine” or “Java VM” mean a virtual machine for the Java
platform.
APRIL 18, 2000 III

Preface

This tutorial introduces you to the APIs, tools, and services provided in the Java 2 Enter-
prise Edition (J2EE) Software Developer Kit (SDK). You can get the free J2EE SDK
(http://java.sun.com/j2ee/download.html) to use for demonstrations, prototyping,
educational use, and verifying J2EE application portability.
To support these uses the J2EE SDK comes with J2EE development and deployment tools,
Java Web Server technology, Cloudscape database, Java Software application server,
Extensible Markup Language (XML) support, the J2EE APIs, and Java Plug-In. Java Plug-
In lets you run Java 2 applets in browsers that support an earlier release of the Java Runtime
Environment (JRE).

Note: This is a work in progress. Links to new lessons are turned on when they become
available. Submit comments and suggestions to [email protected]

PREFACE
IV APRIL 18, 2000

PREFACE
APRIL 18, 2000 V

Contents

Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Lesson 1
A Simple Session Bean. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
Example Thin-Client Multitiered Application 1
J2EE Software and Setup 3
Unix: 3
Windows: 3
Path Settings 3
Unix: 3
Windows: 3
Class Path Settings 4
Unix: 4
Windows: 4
J2EE Application Components 4
Create the HTML File 6
HTML Code 6
Create the Servlet 6
Import Statements 6
init Method 7
doGet Method 7
Servlet Code 9
Create the Session Bean 10
CalcHome 11
Calc 12
CalcBean 12
Compile the Session Bean and Servlet 13
Compile the Session Bean 13
Compile the Servlet 13
Start the J2EE Application Server 14
Unix: 14
Windows: 14
Start the Deploy Tool 14
Unix: 14
Windows: 14
Deploy Tool 15

CONTENTS
APRIL 18, 2000 VI

Assemble the J2EE Application 16


Create J2EE Application EAR file 16
Create Session Bean JAR File 16
Create Web Component WAR File 19
Specify JNDI Name and Root Context 22
Verify and Deploy the J2EE Application 23
Verify 23
Deploy 24
Run the J2EE Application 25
Lesson 2
A Simple Entity Bean . . . . . . . . . . . . . . . . . . . . . . . . . . . . .27
Create the Entity Bean 27
BonusHome 28
Bonus 28
BonusBean 29
Change the Servlet 32
Compile 34
Compile the Entity Bean 34
Compile the Servlet 34
Start the Platform and Tools 35
Unix 35
Windows 35
Assemble and Deploy 35
Uninstall the Application 35
Delete and Create New WAR File 36
Create EJB JAR for the Entity Bean 36
Verify and Deploy the J2EE Application 41
Run the J2EE Application 42
Lesson 3
Cooperating Enterprise Beans . . . . . . . . . . . . . . . . . . . . . .43
Change the Session Bean 44
CalcHome 44
Calc 45
CalcBean 45
Change the Servlet 47
Compile 48
Compile the Entity Bean 49
Compile the Servlet 49
Start the Platform and Tools 49
Unix 50
Windows 50

CONTENTS
APRIL 18, 2000 VII

Assemble the Application 50


Uninstall the Application 50
Create J2EE Application EAR file 50
Create Web Component WAR File 51
Create EJB JAR for the Session and Entity Beans 51
Verify and Deploy the J2EE Application 54
Verify 54
Deploy 54
Run the J2EE Application 56
Lesson 4
JavaServer Pages Technology. . . . . . . . . . . . . . . . . . . . . . .57
Create the JSP Page 58
Comments 60
Directives 60
Declarations 60
Scriptlets 61
Predefined Variables 61
Expressions 61
JSP-Specific Tags 62
Change bonus.html 62
Start the Platform and Tools 63
Unix 63
Windows 63
Remove the WAR File 63
Assemble New WAR FIle 63
Uninstall the Application 63
Create Web Component WAR File 64
Verify and Deploy the J2EE Application 64
Verify 64
Deploy 65
Run the J2EE Application 66
More Information 67
Lesson 5
Adding JavaBeans Technology to the Mix . . . . . . . . . . . .69
About the Example 70
Create bonus.jsp 72
Specify the JavaBean 74
Get the Data 74
Pass the Data to the JavaBean 74
Retrieve Data from the JavaBean 74
Create the JavaBeans Class 75
Bean Properties 77
Constructor 77
Set Methods 77
Get Methods 78

CONTENTS
VIII APRIL 18, 2000

Start the Platform and Tools 80


Unix 80
Windows 80
Remove the WAR File 81
Assemble New WAR FIle 81
Uninstall the Application 81
Create Web Component WAR File 81
Verify and Deploy the J2EE Application 81
Verify 82
Deploy 82
Run the J2EE Application 83
More Information 83
Lesson 6
Extensible Markup Language (XML) . . . . . . . . . . . . . . . 85
Marking and Handling Text 86
Change the JavaBean Class 86
XML Prolog 87
Document Root 87
Child Nodes 87
Other XML Tags 87
JavaBean Code 88
The APIs 91
SAX and DOM 91
J2EE 91
Assemble, Verify, Deploy, and Run 92
More Information 92
Lesson 7
JDBC Technology and Bean-Managed Persistence . . . . 93
Bean Lifecycle 94
Change the BonusBean Code 95
Import Statements 95
Instance Variables 95
Business Methods 96
LifeCycle Methods 96
Create the Database Table 101
createTable.sql 102
cloudTable.bat 102
cloudTable.sh 102
Uninstall J2EE Application 103
Delete and Create EJB JAR File 103
Delete JAR File 103
Create JAR with Session Bean 104
Add the Entity Bean 104
Verify and Deploy the J2EE Application 106
Verify 106
Deploy 106
Run the J2EE Application 107

CONTENTS
APRIL 18, 2000 IX

More Information 108


Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109

CONTENTS
X APRIL 18, 2000

CONTENTS
APRIL 18, 2000 1

Lesson 1
A Simple Session Bean

This lesson introduces you to J2EE applications programming, and the J2EE SDK by show-
ing you how to write a simple thin-client multitiered enterprise application.
The J2EE SDK is a non-commercial operational definition of the J2EE platform and specifi-
cation made freely available by Sun Microsystems for demonstrations, prototyping, and edu-
cational uses. It comes with the J2EE application server, web server, database, J2EE APIs,
and a full-range of development and deployment tools. You will become acquainted with
many of these features and tools as you work through the lessons in this tutorial.
• Example Thin-Client Multitiered Application (page 1)
• J2EE Software and Setup (page 3)
• Path Settings (page 3)
• Path Settings (page 3)
• J2EE Application Components (page 4)
• Create the HTML File (page 6)
• Create the Servlet (page 6)
• Servlet Code (page 9)
• Create the Session Bean (page 10)
• Start the J2EE Application Server (page 14)
• Start the Deploy Tool (page 14)
• Deploy Tool (page 15)
• Assemble the J2EE Application (page 16)
• Verify and Deploy the J2EE Application (page 23)
• Run the J2EE Application (page 25)

Example Thin-Client Multitiered Application


The example thin-client multitiered application for this lesson accepts user input through an
HTML form that invokes a servlet. The servlet uses Java Naming and Directory Interface
(JNDI) APIs to look up a session Bean to perform a calculation on its behalf. Upon receiving

LESSON 1 A SIMPLE SESSION BEAN


2 APRIL 18, 2000

the results of the calculation, the servlet returns the calculated value to the end user in an
HTML page.
This example is a thin-client application because the servlet does not execute any business
logic. The simple calculation is performed by a session Bean executing on the J2EE applica-
tion server. So, the client is thin because it does not handle the processing; the session Bean
does.
As shown in Figure 1, the thin-client servlet is the first tier in this multitier example, and the
application server is the second tier. Multitier or three-tier architecture extends the standard
two-tier client and server model by placing a multithreaded application server between the
client and database.

Browser

Network

Web Server
Tier (Thin-Client
1 Servlet)

Network

Tier Enterprise Beans


2 Application
Server

Network

Tier Database
3 Server

Figure 1 Multitiered Architecture

While this lesson uses only two of the three tiers, Lesson 2 expands this same example to
access the database server in the third tier. Later lessons adapt the example to use JavaSer-
ver Pages and Extensible Markup Language (XML).

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 3

J2EE Software and Setup


To run the lesson examples, you need to download and install the Java 2 SDK Enterprise
Edition (J2EE), Version 1.2 Release (http://java.sun.com/j2ee/downloads.html), and
Java 2 SDK, Standard Edition (http://java.sun.com/jdk/index.html).
The instructions in this tutorial assume these are installed in a J2EE directory under moni-
cap's home directory.

Note: Everywhere monicap is used in a path name, please change it to your own user
name.

Unix:
/home/monicap/J2EE/j2sdkee1.2
/home/monicap/J2EE/jdk1.2.2

Windows:
\home\monicap\J2EE\j2sdkee1.2
\home\monicap\J2EE\jdk1.2.2

The download has the J2EE application server, Cloudscape database, Java Web Server plus
secure socket layer (SSL) also known as HTTP over HTTPS, development and deployment
tools, and the Java APIs for the Enterprise. To use these features, set your path and class path
environment variables as described here.

Path Settings
Path settings make the development and deployment tools accessible from anywhere on your
system. Make sure you place these path settings before any other paths you might have for
other older JDK installations.

Unix:
/home/monicap/J2EE/jdk1.2.2/bin
/home/monicap/J2EE/j2sdkee1.2/bin

Windows:
\home\monicap\J2EE\jdk1.2.2\bin
\home\monicap\J2EE\j2sdkee1.2\bin

LESSON 1 A SIMPLE SESSION BEAN


4 APRIL 18, 2000

Class Path Settings


Class path settings tell the Java 2 development and deployment tools where to find the vari-
ous class libraries they use.

Unix:
/home/monicap/J2EE/j2sdkee1.2/lib/j2ee.jar

Windows:
\home\monicap\J2EE\j2sdkee1.2\lib\j2ee.jar

J2EE Application Components


J2EE applications programmers write J2EE application components. A J2EE application
component is a self-contained functional software unit that is added to and interfaces with
other application components. The applications programmer or an assembler uses the
Deploy tool to assemble application components into a complete J2EE application.
The example for this lesson has two application components: (1) An HTML page and serv-
let, and (2) A session Bean. You will create the components, assemble them into a complete
J2EE application, and deploy and run the application in this lesson.
An application component can consist of a number of elements. For example, the HTML
page and servlet are the two elements in one application component because they work
together. The HTML form invokes the servlet, and the servlet retrieves the data entered onto
the form embedded in the HTML page.
Also, the session Bean is one application component that consists of the session Bean (Cal-
cBean.class), and its home (CalcHome.class) and remote (Calc.class) interfaces. The
home and remote interfaces are the means by which client programs access the session Bean
methods.
Figure 2 shows how the page looks when displayed to the user. The bonus.html file has two
data fields so the user can enter a social security number and a multiplier. When the user
clicks the Submit button, BonusServlet retrieves the end user data, looks up the session
Bean, and passes the user data to the session Bean. The session Bean calculates a bonus and
returns the bonus value to the servlet. The servlet then returns another HTML page with the
bonus value for the end user to view.

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 5

Figure 2 HTML Page

Figure 3 shows how data flows between the browser and the session Bean. The session Bean
executes in the J2EE application server.

Component Component

HTML Form Servlet Session Bean


Browser (Web Server) (Application Server)

bonus.html BonusServlet.class CalcBean.class


Calc.class
CalcHome.class

Figure 3 Data Flow

LESSON 1 A SIMPLE SESSION BEAN


6 APRIL 18, 2000

Create the HTML File


The HTML code for bonus.html is below. The interesting thing about the form HTML code
is the alias used to invoke BonusServlet. When the user clicks the Submit button on the
HTML form, BonusServlet is invoked because it is mapped to the BonusAlias during
application assembly described in Assemble the J2EE Application (page 16).

HTML Code
The example assumes bonus.html is in the /home/monicap/J2EE/ClientCode directory on
Unix. Here and hereafter, Windows users can reverse the slashes to get the correct directory
pathname for their platform.
<HTML>
<BODY BGCOLOR = "WHITE">
<BLOCKQUOTE>
<H3>Bonus Calculation</H3>
<FORM METHOD="GET"
ACTION="BonusAlias">
<P>
Enter social security Number:
<P>
<INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT>
<P>
Enter Multiplier:
<P>
<INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT>
<P>
<INPUT TYPE="SUBMIT" VALUE="Submit">
<INPUT TYPE="RESET">
</FORM>
</BLOCKQUOTE>
</BODY>
</HTML>

Create the Servlet


The servlet code retrieves the user data, looks up the session Bean, passes the data to the ses-
sion Bean, and upon receiving a value back from the session Bean creates an HTML page to
display the returned value to the user. The servlet code is shown in its entirety in Servlet
Code (page 9).

Import Statements
The servlet code begins with import statements for these packages:

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 7

• javax.servlet, which contains generic (protocol-independent) servlet classes. The


HTTPServlet class uses the ServletException class in this package to indicate a
servlet problem.
• javax.servlet.http, which contains HTTP servlet classes. The HttpServlet class
is in this package.
• java.io for system input and output. The HttpServlet class uses the IOException
class in this package to signal that an input or output exception of some kind has
occurred.
• javax.naming for using the Java Naming and Directory Interface (JNDI) APIs to
look up the session Bean home interface.
• javax.rmi for looking up the session Bean home interface and making its remote
server object ready for communications.

init Method
The BonusServlet.init method looks up the session Bean home interface and creates its
instance. The method uses the JNDI name specified during component assembly (calcs) to
get a reference to the home interface by its name. The next line passes the reference and the
home interface class to the PortableRemoteObject.narrow method to be sure the reference
can be cast to type CalcHome.
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc = (CalcHome)PortableRemoteObject.narrow(obj
ref, CalcHome.class);

doGet Method
The parameter list for the doGet method takes a request and response object. The browser
sends a request to the servlet and the servlet sends a response back to the browser. The
method implementation accesses information in the request object to find out who made
the request, what form the request data is in, and which HTTP headers were sent, and uses
the response object to create an HTML page in response to the browser's request.
The doGet method throws an IOException if there is an input or output problem when it
handles the request, and a ServletException if the request could not be handled. To calcu-
late the bonus value, the doGet method creates the home interface and calls its calcBonus
method.
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String socsec = null;
int multiplier = 0;

LESSON 1 A SIMPLE SESSION BEAN


8 APRIL 18, 2000

double calc = 0.0;


PrintWriter out;
response.setContentType("text/html");
String title = "EJB Example";
out = response.getWriter();
out.println("<HTML><HEAD><TITLE>)
out.println(title);
out.println("</TITLE></HEAD><BODY>");

try{
//Retrieve Bonus and Social Security Information
String strMult = request.getParameter(
"MULTIPLIER");
Integer integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
socsec = request.getParameter("SOCSEC");

//Calculate bonus
double bonus = 100.00;
theCalculation = homecalc.create();
calc = theCalculation.calcBonus(multiplier, bo
nus);
}catch(Exception CreateException){
CreateException.printStackTrace();
}

//Display Data
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec: " + socsec + "<P>");
out.println("<P>Multiplier: " + multiplier + "<P
>");
out.println("<P>Bonus Amount: " + calc + "<P>");
out.println("</BODY></HTML>");
out.close();
}

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 9

Servlet Code
Here is the full code. The example assumes the BonusServlet.java file is in the Client-
Code directory on Unix.

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

public class BonusServlet extends HttpServlet {


CalcHome homecalc;
Calc theCalculation;

public void init(ServletConfig config)


throws ServletException{

//Look up home interface


try{
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc =
(CalcHome)PortableRemoteObject.narrow(
objref,
CalcHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
}
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String socsec = null;
int multiplier = 0;
double calc = 0.0;
PrintWriter out;
response.setContentType("text/html");
String title = "EJB Example";
out = response.getWriter();
out.println("<HTML><HEAD><TITLE>");
out.println(title);
out.println("</TITLE></HEAD><BODY>");
try{
//Get Multiplier and Social Security Information
String strMult =
request.getParameter("MULTIPLIER");
Integer integerMult = new Integer(strMult);
multiplier = integerMult.intValue();

LESSON 1 A SIMPLE SESSION BEAN


10 APRIL 18, 2000

socsec = request.getParameter("SOCSEC");
//Calculate bonus
double bonus = 100.00;
theCalculation = homecalc.create();
calc =
theCalculation.calcBonus(multiplier, bonus);
}catch(Exception CreateException){
CreateException.printStackTrace();
}
//Display Data
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec: " + socsec + "<P>");
out.println("<P>Multiplier: " + multiplier + "<P
>");
out.println("<P>Bonus Amount: " + calc + "<P>");
out.println("</BODY></HTML>");
out.close();
}
public void destroy() {
System.out.println("Destroy");
}
}

Create the Session Bean


A session Bean represents a transient conversation with a client. If the server or client
crashes, the session Bean and its data are gone. In contrast, entity Beans are persistent and
represent data in a database. If the server or client crashes, the underlying services ensure
that the entity Bean data is saved.
Because the enterprise Bean performs a simple calculation at the request of BonusServlet
and the calculation can be reinitiated in the event of a crash, it makes sense to use a session
Bean in this example.
Figure 4 shows how the application components work as a complete J2EE application once
they are assembled and deployed. The container, shown in the shaded box, is the interface
between the session Bean and the low-level platform-specific functionality that supports the
session Bean. The container is created during deployment.

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 11

Home
Interface
Session
HTML Form Text Bean
Servlet
Browser
Remote
Interface
Container

Application Server

Figure 4 Application Components

The next sections show the session Bean code. The example assumes the CalcBean.java,
Calc.java, and CalcHome.java files are placed in the /home/monicap/J2EE/Beans direc-
tory on Unix.

Note: While this example shows how to write the example session Bean, it is also pos-
sible to purchase enterprise Beans from a provider and assemble them into a J2EE
application.

CalcHome
BonusServlet does not work directly with the session Bean, but creates an instance of its
home interface. The home interface extends EJBHome and has a create method for creating
the session Bean in its container.
CreateException is thrown if the session Bean cannot be created, and RemoteException is
thrown if a communications-related exception occurs during the execution of a remote
method.
package Beans;

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

public interface CalcHome extends EJBHome {


Calc create() throws CreateException,
RemoteException;
}

LESSON 1 A SIMPLE SESSION BEAN


12 APRIL 18, 2000

Calc
When the home interface is created, the J2EE application server creates the remote interface
and session Bean. The remote interface extends EJBObject and declares the calcBonus
method for calculating the bonus value. This method is required to throw javax.rmi.Remo-
teException, and is implemented by the CalcBean class.

package Beans;

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

public interface Calc extends EJBObject {


public double calcBonus(
int multiplier, double bonus)
throws RemoteException;
}

CalcBean
The session Bean class implements the SessionBean interface and provides behavior for the
calcBonus method. The setSessionContext and ejbCreate methods are called in that
order by the container after BonusServlet calls the create method in CalcHome.
The empty methods are from the SessionBean interface. These methods are called by the
Bean's container. You do not have to provide behavior for these methods unless you need
additional functionality when the Bean is, for example, created or removed from its con-
tainer.
package Beans;

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

public class CalcBean implements SessionBean {

public double calcBonus(int multiplier,


double bonus) {
double calc = (multiplier*bonus);
return calc;
}
//These methods are described in more
//detail in Lesson 2
public void ejbCreate() { }
public void setSessionContext(
SessionContext ctx) { }
public void ejbRemove() { }
public void ejbActivate() { }

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 13

public void ejbPassivate() { }


public void ejbLoad() { }
public void ejbStore() { }
}

Compile the Session Bean and Servlet


To save on typing, the easiest way to compile the session Bean and servlet code is with a
script (on Unix) or a batch file (on Windows).

Compile the Session Bean


Unix
#!/bin/sh
cd /home/monicap/J2EE
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
CPATH=.:$J2EE_HOME/lib/j2ee.jar
javac -d . -classpath "$CPATH" Beans/CalcBean.java
Beans/CalcHome.java Beans/Calc.java

Windows
cd \home\monicap\J2EE
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar
javac -d . -classpath %CPATH% Beans/CalcBean.java
Beans/CalcHome.java Beans/Calc.java

Compile the Servlet


Unix
#!/bin/sh
cd /home/monicap/J2EE/ClientCode
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
CPATH=.:$J2EE_HOME/lib/j2ee.jar:
/home/monicap/J2EE
javac -d . -classpath "$CPATH" BonusServlet.java

Windows
cd \home\monicap\J2EE\ClientCode
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar;
\home\monicap\J2EE
javac -d . -classpath %CPATH% BonusServlet.java

LESSON 1 A SIMPLE SESSION BEAN


14 APRIL 18, 2000

Start the J2EE Application Server


You need to start the J2EE application server to deploy and run the example. The command
to start the server is in the bin directory under your J2EE installation. If you have your path
set to read the bin directory, go to the J2EE directory (so your live version matches what you
see in this text) and type:
j2ee -verbose

Note: Sometimes the J2EE server will not start if Outlook is running.

If that does not work, type the following from the J2EE directory:

Unix:
j2sdkee1.2/bin/j2ee -verbose

Windows:
j2sdkee1.2\bin\j2ee -verbose

The verbose option prints informational messages to the command line as the server starts
up. When you see J2EE server startup complete, you can start the depoloyer tool.

Start the Deploy Tool


To assemble and deploy the J2EE application, you have to start the deploy tool. If you have
your path set to read the bin directory, go to the J2EE directory (so your live version matches
what you see in this text) and type:
deploytool

If that does not work, do the following from the J2EE directory:

Unix:
j2sdkee1.2/bin/deploytool

Windows:
j2sdkee1.2\bin\deploytool

Notes: If a memory access error is encountered when starting deploytool, add an


environment variable called JAVA_FONTS and set the path toc: \<font directory>.
For example c:\winnt\fonts. Also, If a NullPointerException for BasicFi-
leChooserUI is encountered when starting deploytool, be sure you are not starting

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 15

the tool from the root directory (i.e. c:\). If you run it from another location, such as
the bin directory for your j2sdkee1.2 installation, you will not encounter the prob-
lem.

Deploy Tool
The Deploy tool shown in Figure 5 has four main windows. The Local Applications window
displays J2EE applications and their components. The Inspecting window displays informa-
tion on the selected application or components. The Servers window tells you the application
server is running on the local host. And the Server Applications window tells you which
applications have been installed. As you go through the steps to assemble the example J2EE
application, you will see the Local Applications, Inspecting, and Server Applications win-
dows display information.

Figure 5 Deploy Tool

Note: To the right of the Server Applications window is a grayed Uninstall button.
After you deploy the application, you will see the application listed in the Server
Applications window. You can click Uninstall to uninstall the application, make
changes, and redeploy it without having to stop and restart the application server.

LESSON 1 A SIMPLE SESSION BEAN


16 APRIL 18, 2000

Assemble the J2EE Application


To assemble a J2EE application, you first create an Enterprise Archive (EAR) file and then
add the application components to it. In this example, there are the following two application
components:
• A Web Archive (WAR) file that contains the bonus.html and BonusServlet.class
files.
• A Java Archive (JAR) file that contains the three session Bean files: Calc.class, Cal-
cHome.class, and CalcBean.class.

Here is a summary of the assembly steps, which are discussed in more detail below.
1. Create J2EE application EAR file (BonusApp.ear).
2. Create session Bean JAR file (CalcBean.jar).
3. Create web component WAR file (Bonus.war).
4. Specify JNDI name for session Bean (calcs).
5. Specify Root Context (BonusRoot).

Create J2EE Application EAR file


From the File menu, select New Application.
In the New Application dialog box that appears, type BonusApp for the Application Name.
Click the .. button next to the Location field to open the file chooser to select the location
where you want the application EAR file to be saved. In this example, that directory is
/export/home/monicap/J2EE.

In the New Application file chooser, locate the directory where you want to place the appli-
cation EAR file, and in the File name field, type BonusApp.
Click New Application.
Click OK.
The BonusApp file is now listed in the Local Applications window, and the Inspector window
to the right shows the display name, location, and contents information for BonusApp. The
meta information shown in the contents window describes the JAR file and J2EE applica-
tion, and provides runtime information about the application.

Create Session Bean JAR File


Enterprise Beans (entity and session Beans) are bundled into a Java Archive (JAR) file.
From the File menu, select New Enterprise Bean. The New Enterprise Bean Wizard
starts and displays an Introduction dialog box that summarizes the steps you are about to
take. After reading it over, click Next.
In the EJB JAR dialog box, specify the following information:

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 17

Enterprise Bean will go in: BonusApp


Display name: BonusApp
Description: A simple session Bean that
calculates a bonus. It has one method

Click Add. There are two Add buttons on this screen. Make sure you click the second one
down that is next to the Contents window.
In the Add Contents to .JAR dialog box, go to the J2EE directory. You can either type the
path name or use the browser to get there. Once at the J2EE directory, double click on Beans
to display the contents of the Beans directory.
Select Calc.class.
Click Add.
Select CalcHome.class.
Click Add.
Select CalcBean.class.
Click Add.
The Add Contents to .JAR dialog box should look like the one in Figure 6. The important
thing is that the Enterprise Bean JAR classes show the Beans directory prefixed to the class
names.

LESSON 1 A SIMPLE SESSION BEAN


18 APRIL 18, 2000

Figure 6 Select Session Bean Class Files

Click OK.
You should now be back at the EJB JAR dialog box. Beans/Calc.class, Beans/Cal-
cHome.class, and Beans/CalcBean.class should appear in the Contents window.

Click Next.
In the General dialog box, make sure the following information is selected:
classname: Beans.CalcBean
Home interface: Beans.CalcHome
Remote interface: Beans.Calc
Bean type: Session and Stateless

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 19

In the same dialog box, specify the display name (the name that appears when when the JAR
file is added to BonusApp in the Local Applications window, and provide a description of
the JAR file contents.
Display Name: CalcJar
Description: This JAR file contains the CalcBean session Bean.
Click Next.
The Environment Entries dialog box appears. This example does not use properties (envi-
ronment entries) so you can click Finish.
To verify the JAR file was indeed added, go to the Local Applications window and click the
key graphic in front of the BonusApp EAR file. You will see the JAR file. Click the key
graphic in front of the JAR file to see the session Bean.
General inspection information appears in the right window for BonusApp. You can see Gen-
eral inspection information for CalcJar or CalcBean by selecting them.

Create Web Component WAR File


Web clients (HTML pages and their corresponding servlets, or JavaServer Pages) are bun-
dled into a Web Archive (WAR) file.
From the File menu, select New Web Component. The New Web Component Wizard starts
and displays a window that summarizes the steps you are about to take. After reading it over,
click Next.
In the WAR File General Properties dialog box, provide the following information:
WAR file: BonusApp
Display name: BonusAppWar
Description: This war file contains a servlet and an
html page.

Click Add.
In the Add Contents to WAR dialog box, go to the ClientCode directory. You can either
type the path name or use the browser to get there.
Select BonusServlet.class. Make sure the WAR contents shows the listing as bonus.html
without the ClientCode directory prefixed to the name.

LESSON 1 A SIMPLE SESSION BEAN


20 APRIL 18, 2000

Figure 7 Add BonusServlet.class

Click Add.
Click Next.
Choose the ClientCode directory again.
Select bonus.html. Be sure the WAR contents shows the listing as bonus.html without
the ClientCode directory prefixed to the name.
Click Add.
The Add Contents to WAR dialog box should look like the one in Figure 8.

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 21

Figure 8 Add bonus.html

Click Finish.
In the WAR File General Properties dialog box, click Next.
In the Choose Component Type dialog box, select Describe a servlet (if it is not already
selected), and click Next.
In the Component General Properties dialog box, make sure BonusServlet is selected for
the Servlet Class, and then enter a display name (BonusServlet), and a description. You
can ignore the Startup and load sequence setting here because this example uses only one
servlet.

LESSON 1 A SIMPLE SESSION BEAN


22 APRIL 18, 2000

Click Next on the Parameters dialog box. BonusServlet does not use any initialization
parameters.
In the Aliases dialog box, click Add.
In the URL Mappings list, type BonusAlias. This is the same alias name you put in the
ACTION field of the HTML form embedded in the bonus.html file.
Click Finish.
In the Content pane, you can see that the WAR file contains an XML file with structural and
attribute information on the web application, the bonus.html file, and the BonusServlet
class file. The WAR file format is such that all servlet classes go in an entry starting with
Web-INF/classes. However, when the WAR is deployed, the BonusServlet class is placed
in a Context Root directory under public_html. This placement is the convention for Serv-
let 2.2 compliant web servers.
If you want to change the display name or description, put your cursor in the appropriate
field in the window and change them as you wish. Your edits take effect with you press the
Return key.

Specify JNDI Name and Root Context


Before you can deploy the BonusApp application and its components, you have to specify the
JNDI name BonusServlet uses to look up the CalcBean session Bean, and specify a context
root directory where the deployer will put the web components.

JNDI Name
To specify the JNDI name, select the BonusApp EAR file in the Local Applications window.
The Inspecting window displays tabs at the top, and one of those tabs is JNDI Names. Select
it.
The Inspecting window shows a three-column display with one row. CalcJar is listed in the
left column, and in the far right column under JNDI name, type calcs and press the Return
key. That JNDI name is the same JNDI name passed to the BonusServlet.lookup method.

Context Root
Click the Web Context tab at the top of the Inspecting window. You will see BonusAppWar
in the left column. Type BonusRoot in the right column and press the Return key. During
deployment the BonusRoot directory is created under the public_html directory in your
J2sdkee1.2 installation, and the bonus.html file and BonusServlet class are copied
into it as shown in Figure 9.

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 23

j2sdkee1.2

public_html

BonusRoot

WEB-INF bonus.html

classes

BonusServlet.class

Figure 9 Context Root Directory Structure

Verify and Deploy the J2EE Application


Before you deploy the application, it is a good idea to run the verifier. The verifier will pick
up errors in the application components such as missing enterprise Bean methods that the
compiler does not catch.

Verify
With BonusApp selected, choose Verifier from the Tools menu. In the dialog that pops up,
click OK. The window should tell you that all tests passed. That is, if you used the session
Bean code provided for this lesson. Close the verifier window because you are now ready to
deploy the application.

Note: In the Version 1.2 software you might get a tests app.WebURI error. This
means the deploy tool did not put a .war extension on the WAR file during WAR file cre-
ation. This is a minor bug and the J2EE application deploys just fine in spite of it.

LESSON 1 A SIMPLE SESSION BEAN


24 APRIL 18, 2000

Deploy
From the Tools menu, choose Deploy Application. A Deploy BonusApp dialog box pops
up. Verify that the Target Server selection is either localhost or the name of the host running
the J2EE server.
Do not check the Return Client Jar box. The only time you need to check this box is when
you deploy a stand-alone application for the client program. This example uses a servlet and
HTML page so this box should not be checked. Checking this box creates a JAR file with
the deployment information needed by a stand-alone application.
Click Next.
Make sure the JNDI name shows calcs. If it does not, type it in yourself, and press the
Return key.

Click Next.
Make sure the Context Root name shows BonusRoot. If it does not, type it in yourself and
press the Return key.
Click Next.
Click Finish to start the deployment. A dialog box pops up that displays the status of the
deployment operation. When it is complete, the three bars on the left will be completely
shaded as shown in Figure 10. When that happens, click OK.

LESSON 1 A SIMPLE SESSION BEAN


25 APRIL 18, 2000

Figure 10 Deploy Application

Run the J2EE Application


The web server runs on port 8000 by default. To open the bonus.html page point your
browser to http://localhost:8000/BonusRoot/bonus.html, which is where the Deploy
tool put the HTML file. If you need to use a different port because port 8000 is being used
for something else, edit the web.properties file in the ~/J2EE/j2sdkee1.2/config direc-
tory and restart the J2EE server.
Fill in a social security number and multiplier, and click the Submit button. BonusServlet
processes your data and returns an HTML page with the bonus calculation on it.
Bonus Calculation

Soc Sec: 777777777


Multiplier: 25

Bonus Amount 2500.0

LESSON 1 A SIMPLE SESSION BEAN


26 APRIL 18, 2000

LESSON 1 A SIMPLE SESSION BEAN


APRIL 18, 2000 27

Lesson 2
A Simple Entity Bean

This lesson expands the Lesson 1 example to use an entity Bean. BonusServlet calls on the
entity Bean to save the social security number and bonus information to and retrieve it from
a database table. This database access functionality adds the third and final tier to the thin-
client, multitiered example started in Lesson 1.
The J2EE SDK comes with Cloudscape database, and you need no additional setup to your
environment for the entity Bean to access it. In fact in this example, you do not write any
SQL or JDBC code to create the database table or perform any database access operations.
The table is created and the SQL code generated with the Deploy tool during assembly and
deployment.
• Create the Entity Bean (page 27)
• Change the Servlet (page 32)
• Compile (page 34)
• Start the Platform and Tools (page 35)
• Assemble and Deploy (page 35)
• Run the J2EE Application (page 42)

Create the Entity Bean


An entity Bean represents persistent data stored in one row of a database table. When an
entity Bean is created, the data is written to the appropriate database table row, and if the
data in an entity Bean is updated, the data in the appropriate database table row is also
updated. The database table creation and row updates all occur without your writing any
SQL or JDBC code.
Entity Bean data is persistent because it survives crashes. If a crash occurs while the data in
an entity Bean is being updated, the entity Bean data is automatically restored to the state of
the last committed database transaction. If the crash occurs in the middle of a database trans-
action, the transaction is backed out to prevent a partial commit from corrupting the data.

LESSON 2 A SIMPLE ENTITY BEAN


28 APRIL 18, 2000

BonusHome
The main difference between the CalcHome session Bean code and the BonusHome entity
Bean code shown below is the addition of the findByPrimaryKey finder method. This
method takes the primary key as a parameter, which is a social security number. The primary
key is used to retrieve the table row with a primary key value that corresponds to the social
security number passed to this method.
The create method takes the bonus value and primary key as parameters. When
BonusServlet instantiates the home interface and calls its create method, the container
creates a BonusBean instance and calls its ejbCreate method. The BonusHome.create and
BonusBean.ejbCreate methods must have the same signatures, so the bonus and primary
key values are passed from the home interface to the entity Bean by way of the entity Bean's
container. If a row for a given primary key (social security) number already exists, a
java.rmi.RemoteException is thrown that is handled in the BonusServlet client code.

package Beans;

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

public interface BonusHome extends EJBHome {


public Bonus create(double bonus, String socsec)
throws CreateException, RemoteException;
public Bonus findByPrimaryKey(String socsec)
throws FinderException, RemoteException;
}

Bonus
After the home interface is created, the container creates the remote interface and entity
Bean. The Bonus interface declares the getBonus and getSocSec methods so the servlet can
retrieve data from the entity Bean.
package Beans;

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

public interface Bonus extends EJBObject {


public double getBonus() throws RemoteException;
public String getSocSec() throws RemoteException;
}

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 29

Component Component

Browser Servlet Session Bean

bonus.html BonusServlet.class CalcBean.class


Calc.class
CalcHome.class

Component

Entity Bean

BonusBean.class
Bonus.class
BonusHome.class

Database

BonusBean
BonusBean is a container managed entity Bean. This means the container handles data per-
sistence and transaction management without your writing code to transfer data between the
entity Bean and the database or define transaction boundaries.
If for some reason you want the entity Bean to manage its own persistence or transactions,
you would provide implementations for some of the empty methods shown in the BonusBean
code below. The following links take you to documents that describe Bean-managed persis-
tence and transactions, and a later lesson in this tutorial will cover Bean-managed transac-
tions.
• Chapter 3 of the Writing Advanced Applications tutorial.
• Chapter 4 of the Enterprise JavaBeans Developer's Guide.

LESSON 2 A SIMPLE ENTITY BEAN


30 APRIL 18, 2000

When BonusServlet calls BonusHome.create, the container calls the BonusBean.setEnti-


tyContext method. The EntityContext instance passed to the setEntityContext method
has methods that let the Bean return a reference to itself or get its primary key.
Next, the container calls the ejbCreate method. The ejbCreate method assigns data to the
Bean's instance variables, and then the container writes that data to the database.
The ejbPostCreate method is called after the ejbCreate method and performs any pro-
cessing needed after the Bean is created. This simple example does no post-create process-
ing.
The rest of the empty methods are callback methods called by the container to notify the
Bean that some event is about to occur. You would provide behavior for some of these meth-
ods if you are using Bean-managed persistence, and others if you need to provide Bean-spe-
cific cleanup or initialization operations. These cleanup and initialization operations take
place at specific times during the Bean's lifecycle, and the container notifies the Bean and
calls the applicable method at the appropriate time. Here is a brief description of the empty
methods:
• The ejbPassivate and ejbActivate methods are called by the container before the
container swaps the Bean in and out of storage. This process is similar to the virtual-
memory concept of swapping a memory page between memory and disk.
• The container calls the ejbRemove method if the home interface has a corresponding
remove method that gets called by the client.
• The ejbLoad and ejbStore methods are called by the container before the container
synchronizes the Bean's state with the underlying database.
The getBonus and getSocSec methods are called by clients to retrieve data stored in the
instance variables. This example has no setXXX methods, but if it did, clients would call
them to change the data in the Bean's instance variables. Any changes to the instance vari-
ables result in an update to the table row in the underlying database.
package Beans;

import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;

public class BonusBean implements EntityBean {

public double bonus;


public String socsec;
private EntityContext ctx;

public double getBonus() {

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 31

return this.bonus;
}
public String getSocSec() {
return this.socsec;
}

public String ejbCreate(double bonus,


String socsec)
throws CreateException{
//Called by container after setEntityContext
this.socsec=socsec;
this.bonus=bonus;
return null;
}

public void ejbPostCreate(double bonus,


String socsec) {
//Called by container after ejbCreate
}

//These next methods are callback methods that


//are called by the container to notify the
//Bean some event is about to occur

public void ejbActivate() {


//Called by container before Bean
//swapped into memory
}

public void ejbPassivate() {


//Called by container before
//Bean swapped into storage
}

public void ejbRemove() throws RemoteException {


//Called by container before
//data removed from database
}

public void ejbLoad() {


//Called by container to
//refresh entity Bean's state
}

public void ejbStore() {


//Called by container to save
//Bean's state to database
}

LESSON 2 A SIMPLE ENTITY BEAN


32 APRIL 18, 2000

public void setEntityContext(EntityContext ctx){


//Called by container to set Bean context
}

public void unsetEntityContext(){


//Called by container to unset Bean context
}
}

Change the Servlet


The BonusServlet program is very similar to the Lesson 1 version with changes in the init
and doGet methods. The init method for this lesson looks up both the CalcBean session
Bean, and the BonusBean entity Bean.
public class BonusServlet extends HttpServlet {
CalcHome homecalc;
Calc theCalculation;
BonusHome homebonus;
Bonus theBonus, record;

public void init(ServletConfig config)


throws ServletException{
try {
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("bonus");
Object objref2 = ctx.lookup("calcs");
homebonus=(
BonusHome)PortableRemoteObject.narrow(
objref, BonusHome.class);
homecalc=(CalcHome)
PortableRemoteObject.narrow(
objref2, CalcHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
}

The try statement in the doGet method creates the CalcBean and BonusBean home inter-
faces. After calling calcBonus to calculate the bonus, the BonusHome.create method is
called to create an entity Bean instance and a corresponding row in the underlying database
table. After creating the table, the BonusHome.findByPrimaryKey method is called to
retrieve the same record by its primary key (social security number). Next, an HTML page is

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 33

returned to the browser showing the data originally passed in, the calculated bonus, and the
data retrieved from the database table row.
The catch statement catches and handles duplicate primary key values (social security num-
bers). The underlying database table cannot have two rows with the same primary key, so if
you pass in the same social security number, the servlet catches and handles the error before
trying to create the entity Bean. In the event of a duplicate key, the servlet returns an HTML
page with the original data passed in, the calculated bonus, and a duplicate key error mes-
sage.
try {
//Retrieve Bonus and Social Security Information
String strMult = request.getParameter(
"MULTIPLIER");//Calculate bonus
Integer integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
socsec = request.getParameter("SOCSEC");
//Calculate bonus
double bonus = 100.00;
theCalculation = homecalc.create();
calc = theCalculation.calcBonus(
multiplier, bonus);
//Create row in table
theBonus = homebonus.create(calc, socsec);
record = homebonus.findByPrimaryKey(socsec);
//Display data
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec passed in: " +
theBonus.getSocSec() + "<P>");
out.println("<P>Multiplier passed in: " +
multiplier + "<P>");
out.println("<P>Bonus Amount calculated: " +
theBonus.getBonus() + "<P>");
out.println("<P>Soc Sec retrieved: " +
record.getSocSec() + "<P>");
out.println("<P>Bonus Amount retrieved: " +
record.getBonus() + "<P>");
out.println("</BODY></HTML>");
//Catch duplicate key error
} catch (javax.ejb.DuplicateKeyException e) {
String message = e.getMessage();
//Display data
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec passed in: " +
socsec + "<P>");
out.println("<P>Multiplier passed in: " +
multiplier + "<P>");
out.println("<P>Bonus Amount calculated: " +

LESSON 2 A SIMPLE ENTITY BEAN


34 APRIL 18, 2000

calc + "<P>");
out.println("<P>" + message + "<P>");
out.println("</BODY></HTML>");
} catch (Exception CreateException) {
CreateException.printStackTrace();
}
}

Compile
First, compile the entity Bean and servlet. Refer to Lesson 1 for path and classpath settings,
and information on where to place the source files.

Compile the Entity Bean


Unix
#!/bin/sh
cd /home/monicap/J2EE
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
CPATH=.:$J2EE_HOME/lib/j2ee.jar
javac -d . -classpath "$CPATH" Beans/BonusBean.java
Beans/BonusHome.java Beans/Bonus.java

Windows
cd \home\monicap\J2EE
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar
javac -d . -classpath %CPATH% Beans/BonusBean.java
Beans/BonusHome.java Beans/Bonus.java

Compile the Servlet


Unix:
cd /home/monicap/J2EE/ClientCode
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
CPATH=.:$J2EE_HOME/lib/j2ee.jar:/home/monicap/J2EE
javac -d . -classpath "$CPATH" BonusServlet.java

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 35

Windows:
cd \home\monicap\J2EE\ClientCode
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar;
\home\monicap\J2EE
javac -d . -classpath %CPATH% BonusServlet.java

Start the Platform and Tools


To run this example, you need to start the J2EE server, the Deploy tool, and Cloudscape
database. In different windows, type the following commands:
j2ee -verbose
deploytool
cloudscape -start

If that does not work, type this from the J2EE directory:

Unix
j2sdkee1.2/bin/j2ee -verbose
j2sdkee1.2/bin/deploytool
j2sdkee1.2/bin/cloudscape -start

Windows
j2sdkee1.2\bin\j2ee -verbose
j2sdkee1.2\bin\deploytool
j2sdkee1.2\bin\cloudscape -start

Assemble and Deploy


Before you can redeploy the J2EE application with the changes for this lesson, you have to
uninstall the Lesson 1 J2EE application. You can do this any time before you deploy, but just
to make sure you do not forget, do it now.

Uninstall the Application


At the bottom of the Deploy tool is a window listing BonusApp with an Uninstall button to
the right. Click Uninstall.

LESSON 2 A SIMPLE ENTITY BEAN


36 APRIL 18, 2000

Delete and Create New WAR File


The web archive (WAR) file contains BonusServlet and bonus.html. Because you have
changed BonusServlet, you have to delete the WAR file from the application, recreate it
with the new BonusServlet, and add the new WAR file back to the J2EE application.
Click the BonusApp application in the Local Applications window so you can see its
application components. Select BonusWar so it is outlined highlighted.
At the top of the Deploy tool, there is an Edit menu. Select Delete.
Now, go through the steps to create the WAR file. These steps are outlined in Lesson 1 and
summarized below:
• Select File.New Web Component from the menus at the top.
• Introduction: Read and Click Next
• War File General Properties: Specify BonusWar for the display name. Click Add, go
to the ClientCode directory, add BonusServlet.class, Click Next, go to the Client-
Code directory, add bonus.html, click Finish.
• War File General Properties: Click Next.
• Choose Component Type:. Make sure Describe a servlet is selected. Click Next.
• Component General Properties: Make the display name BonusServlet. Click Next.
• Skip Parameters. Click Next.
• Aliases: Specify BonusAlias for URL Mappings. Click Finish.
In the Inspecting window, select Web Context and specify BonusRoot.

Create EJB JAR for the Entity Bean


The steps to creating the EJB JAR for the entity Bean are very similar to the steps for the ses-
sion Bean covered in Lesson 1. There are a few differences, however, and those differences
are explained here.

Note: In this lesson, the entity Bean goes in a separate JAR file from the session Bean
to continue the example from Lesson 1 with the least number of changes.

Because these Beans have related functionality, however, you could bundle and deploy them
in the same JAR file. You will see how to bundle related Beans in the same JAR file in Les-
son 3.
• Select File.New Enterprise Bean from the menus at the top.
• Introduction: Read and click Next.

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 37

• EJB JAR: Make sure BonusApp shows in the Enterprise Bean will go in field. Spec-
ify BonusJar as the display name. Click Add (the one next to the Contents window).
Toggle the directory so the Beans directory displays with its contents.
• Select Bonus.class, Click Add.
• Select BonusBean.class. Click Add.
• Select BonusHome.class. Click Add.
• Click OK.

Figure 11 Adding Classes to BonusJar

• EJB JAR: Click Next.

LESSON 2 A SIMPLE ENTITY BEAN


38 APRIL 18, 2000

• General: Make sure Beans.BonusBean is the classname, Beans.BonusHome is the


Home interface, and Beans.Bonus is the Remote interface. Enter BonusBean as the dis-
play name. Click Entity. Click Next.
• Entity Settings: Select Container managed persistence. In the window below,
check bonus and socsec. The primary key class is java.lang.String, and the pri-
mary key field name is socsec. Note that the primary key has to be a class type. Prim-
itive types are not valid for primary keys. Click Next.
• Environment Entries: Click Next. This simple entity Bean does not use properties
(environment entries).
• Enterprise Bean References: Click Next. This simple entity Bean does not reference
other enterprise Beans.
• Resource References: Click Next. This simple entity Bean does not look up a data-
base or JavaMail session object.
• Security: Click Next. This simple entity Bean does not use security roles.
• Transaction Management: Select Container-managed transactions (if it is not
already selected. In the list below make create, findByPrimaryKey, getBonus and
getSocSec required. This means the container starts a new transaction before running
these methods. The transaction commits just before the methods end. You can find
more information on these transaction settings in Chapter 6 of the Enterprise Java-
Beans Developer's Guide. Click Next.
• Click Finish.

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 39

Figure 12 Transaction Management

• Transaction Management: Click Finish.


• In the Local Applications window, select BonusApp. In the Inspecting window,
select JNDI names, give BonusBean the JNDI name of bonus, and press the Return key.
Before the J2EE application can be deployed, you need to specify deployment settings for
the entity Bean and generate the SQL. Here is how to do it:
• In the Local Applications window, select BonusBean.
• In the Inspecting window, select Entity, and click the Deployment Settings button
to the lower right.
• In the Deployment Settings window, specify jdbc/Cloudscape (with a capital C on
Cloudscape) for the Database JNDI name, press Return, make sure the Create table

LESSON 2 A SIMPLE ENTITY BEAN


40 APRIL 18, 2000

on deploy and Delete table on Deploy boxes are checked, and click Generate SQL
now.

Note: If you get an error that the connection was refused, start the database as
described in Start the Platform and Tools (page 35).

Figure 13 Generate SQL and Database Table

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 41

• When the SQL generation completes, select the findByPrimaryKey method in the EJB
method box. To the right a SQL statement appears. It should read SELECT “socsec”
FROM “BonusBeanTable” WHERE “socsec”=?. The question mark (?) represents the
parameter passed to the findByPrimaryKey method.
• Click OK.

Verify and Deploy the J2EE Application


With BonusEar selected, choose Verifier from the Tools menu. In the dialog that pops up,
click OK. The window should tell you that all tests passed. That is, if you used the session
Bean code provided for this lesson. Close the verifier window because you are now ready to
deploy the application.

Note: In the Version 1.2 software you might get a tests app.WebURI error. The J2EE
application deploys in spite of it. I’ll try to find out what causes this error.

Select Tools.Deploy Application from the menus at the top. If you did not uninstall the
application first, you are prompted to do it now.
Do not check the Return Client Jar box.
Click Next.
Make sure the JNDI name shows calcs. If it does not type it in yourself, and press the
Returnkey.
Click Next.
Make sure the Context Root name shows BonusRoot. If it does not, type it in yourself and
press the Return key.
Click Next.
Click Finish to start the deployment. When deployment completes, click OK.

LESSON 2 A SIMPLE ENTITY BEAN


42 APRIL 18, 2000

Run the J2EE Application


The web server runs on port 8000 by default. To open the bonus.html page point your
browser to http://localhost:8000/BonusRoot/bonus.html, which is where the Deploy
tool put the HTML file.
Fill in a social security number and multiplier, and click the Submit button. BonusServlet
processes your data and returns an HTML page with the bonus calculation on it.
Bonus Calculation

Soc Sec passed in: 777777777


Multiplier passed in: 25
Bonus Amount calculated: 2500.0
Soc Sec retrieved: 7777777777
Bonus Amount retrieved: 2500.0

If you go back to bonus.html and change the multiplier to 2, but use the same social secu-
rity number, you see this:
Bonus Calculation
Soc Sec passed in: 777777777
Multiplier passed in: 2
Bonus Amount calculated: 200.0
Duplicate primary key.

LESSON 2 A SIMPLE ENTITY BEAN


APRIL 18, 2000 43

Lesson 3
Cooperating Enterprise Beans

In Lesson 2 A Simple Entity Bean (page 27), the servlet looks up and creates a session Bean
to perform a bonus calculation, and then looks up and creates an Entity Bean to store the
bonus value and related social security number. This lesson modifies the example so the ses-
sion Bean looks up and creates the entity Bean. Because the session and entity Bean work
together, they are bundled into one JAR file for deployment.
• Change the Session Bean (page 44)
• Change the Servlet (page 47)
• Compile (page 48)
• Start the Platform and Tools (page 49)
• Assemble the Application (page 50)
• Verify and Deploy the J2EE Application (page 54)
• Run the J2EE Application (page 56)

LESSON 3 COOPERATING ENTERPRISE BEANS


44 APRIL 18, 2000

Change the Session Bean


In this lesson and as shown in Figure 14, the entity Bean is a client of the session Bean. This
means the entity Bean gets its data from the session Bean instead of from BonusServlet as
it did in Lesson 2 A Simple Entity Bean (page 27). So, the calcBonus method in the session
Bean is modified to take the social security number as a parameter and create the entity
Bean.

HTML Form Servlet Session Bean


Browser (Web Server) (Application Server)

bonus.html BonusServlet.class calcBonus method


getRecord method

Entity Bean

Database

Figure 14 Beans Working Together

CalcHome
The CalcHome interface is unchanged. It has the same create method that returns an
instance of the remote interface.
package Beans;

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

public interface CalcHome extends EJBHome {


public Calc create()
throws CreateException, RemoteException;
}

LESSON 3 COOPERATING ENTERPRISE BEANS


APRIL 18, 2000 45

Calc
The calcBonus method in the Calc interface is changed to take the social security number as
a parameter. This is so CalcBean can pass the bonus and social security number to the entity
Bean after calculating the bonus value. A new getRecord method is added so CalcBean can
find an entity Bean by its primary key (the social security number).
Also, the calcBonus method signature throws DuplicateKeyException and CreateExcep-
tion. This is so BonusServlet can catch and handle either of these exception conditions.
DuplicateKeyException descends from CreateException. If you design the calcBonus
method to throw DuplicateKeyException, but catch CreateException, DuplicateKeyEx-
ception is not thrown. The way around this is to have calcBonus throw both Dupli-
cateKeyException and CreateException.

package Beans;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;
import javax.ejb.DuplicateKeyException;
import javax.ejb.CreateException;

public interface Calc extends EJBObject {


public Bonus calcBonus(int multiplier,
double bonus,
String socsec)
throws RemoteException,
DuplicateKeyException,
CreateException;
public Bonus getRecord(String socsec)
throws RemoteException;

CalcBean
The code to create the entity Bean is moved from BonusServlet to the CalcBonus method
so the bonus and social security number can be written to the entity Bean after the bonus is
calculated. The homebonus variable is an instance variable so it can be used in the calcBo-
nus method to look up the entity Bean and in the getRecord method to locate the entity
Bean corresponding to the social security number.
package Beans;

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

LESSON 3 COOPERATING ENTERPRISE BEANS


46 APRIL 18, 2000

import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.ejb.RemoveException;
import javax.ejb.DuplicateKeyException;
import javax.ejb.CreateException;

public class CalcBean implements SessionBean {


BonusHome homebonus;
//Throw DuplicateKeyException and CreateException
//so BonusServlet can catch and handle these
//exception conditions.
public Bonus calcBonus(int multiplier,
double bonus, String socsec)
throws DuplicateKeyException,
CreateException {
Bonus theBonus = null;
double calc = (multiplier*bonus);
try {
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("bonus");
homebonus = (BonusHome)
PortableRemoteObject.narrow(
objref, BonusHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
//Store data in entity Bean
try {
theBonus = homebonus.create(calc, socsec);
} catch (java.rmi.RemoteException e) {
String message = e.getMessage();
e.printStackTrace();
}
return theBonus;
}

public Bonus getRecord(String socsec) {


Bonus record = null;
//Use primary key to retrieve data from entity Bean
try {
record = homebonus.findByPrimaryKey(socsec);
} catch (java.rmi.RemoteException e) {
String message = e.getMessage();
} catch (javax.ejb.FinderException e) {
e.printStackTrace();
}
return record;
}

LESSON 3 COOPERATING ENTERPRISE BEANS


APRIL 18, 2000 47

public void ejbCreate() { }


public void setSessionContext(
SessionContext context){
}
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbLoad() { }
public void ejbStore() { }
}

Change the Servlet


The BonusServlet program is very similar to the version in Lesson 2 A Simple Entity Bean
(page 27) with changes in the init and doGet methods. The init method for this lesson
looks up the CalcBean session Bean only.
public class BonusServlet extends HttpServlet {
CalcHome homecalc;
Calc theCalculation;
//Need Bonus variables because CalcBean methods
//called in the doGet method return instances
//of type Bonus
Bonus theBonus, record;

public void init(ServletConfig config)


throws ServletException{
try {
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc = (CalcHome)
PortableRemoteObject.narrow(
objref, CalcHome.class);
} catch (Exception NamingException) {
NamingException.printStackTrace();
}
}

The try statement in the doGet method calculates the bonus, creates the session Bean home
interface, and calls the calcBonus and getRecord methods. If the methods successfully
complete, an HTML page is returned showing the data retrieved from the entity Bean. If
DuplicateKeyException is thrown by the calcBonus method an HTML page is returned
showing the social security number and multiplier passed in, and the exception message,
Duplicate primary key.

LESSON 3 COOPERATING ENTERPRISE BEANS


48 APRIL 18, 2000

As before in Lesson 2 A Simple Entity Bean (page 27), the catch statement catches and
handles duplicate primary key values (social security numbers).
try {
//Retrieve Bonus and Social Security Information
String strMult = request.getParameter(
"MULTIPLIER");//Calculate bonus
Integer integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
socsec = request.getParameter("SOCSEC");
//Calculate bonus
double bonus = 100.00;
theCalculation = homecalc.create();
//Call session Bean
//Pass 3 parameters:multiplier, bonus, and socsec
theBonus = theCalculation.calcBonus(
multiplier, bonus, socsec);
record = theCalculation.getRecord(socsec);
//Display data returned by session Bean
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec retrieved: " +
record.getSocSec() + "<P>");
out.println("<P>Bonus Amount retrieved: " +
record.getBonus() + "<P>");
out.println("</BODY></HTML>");
} catch (javax.ejb.DuplicateKeyException e) {
String message = e.getMessage();
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec passed in: " + socsec +
"<P>");
out.println("<P>Multiplier passed in: " +
multiplier + "<P>");
out.println("</BODY></HTML>");
} catch (Exception CreateException) {
CreateException.printStackTrace();
}

Compile
First, compile the entity Bean and servlet. Refer to Lesson 1 for path and classpath settings,
and information on where to place the source files.

LESSON 3 COOPERATING ENTERPRISE BEANS


APRIL 18, 2000 49

Compile the Entity Bean


Unix
#!/bin/sh
cd /home/monicap/J2EE
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
CPATH=.:$J2EE_HOME/lib/j2ee.jar
javac -d . -classpath "$CPATH" Beans/BonusBean.java
Beans/BonusHome.java Beans/Bonus.java

Windows
cd \home\monicap\J2EE
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar
javac -d . -classpath %CPATH% Beans/BonusBean.java
Beans/BonusHome.java Beans/Bonus.java

Compile the Servlet


Unix:
cd /home/monicap/J2EE/ClientCode
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
CPATH=.:$J2EE_HOME/lib/j2ee.jar:
/home/monicap/J2EE
javac -d . -classpath "$CPATH" BonusServlet.java

Windows:
cd \home\monicap\J2EE\ClientCode
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2 set
CPATH=.;%J2EE_HOME%\lib\j2ee.jar:\home\monicap\J2EE
javac -d . -classpath %CPATH% BonusServlet.java

Start the Platform and Tools


To run this example, you need to start the J2EE server, the Deploy tool, and Cloudscape
database. In different windows, type the following commands:
j2ee -verbose
deploytool
cloudscape -start

If that does not work, type this from the J2EE directory:

LESSON 3 COOPERATING ENTERPRISE BEANS


50 APRIL 18, 2000

Unix
j2sdkee1.2/bin/j2ee -verbose
j2sdkee1.2/bin/deploytool
j2sdkee1.2/bin/cloudscape -start

Windows
j2sdkee1.2\bin\j2ee -verbose
j2sdkee1.2\bin\deploytool
j2sdkee1.2\bin\cloudscape -start

Assemble the Application


Before you can redeploy the J2EE application with the changes for this lesson, you have to
uninstall the Lesson 2 J2EE application. You can do this any time before you deploy, but just
to make sure you do not forget, do it now.

Uninstall the Application


At the bottom of the Deploy tool is a window listing BonusApp with an Uninstall button to
the right. Click Uninstall.

Create J2EE Application EAR file


Rather than update the J2EE application from Lessons 1 and 2, these steps create a whole
new J2EE application. You can either delete the existing J2EE application or leave it. If you
leave the BonusApp application, make sure the 2BonusApp application which you are about
to create is selected when you go on and create the WAR and JAR files to go with it. If it is
not selected, the WAR and JAR files might be added to the BonusApp J2EE application
instead. You can use the cut, paste, and delete options on the Edit menu to move components
from one application to another.
• From the File menu, select New Application.
• In the New Application dialog box that appears, type BonusApp for the Application
Name.
• Click the .. button next to the Location field to open the file chooser to select the loca-
tion where you want the application ear file to be saved. In this example, that directory
is /export/home/monicap/J2EE.
• In the New Application file chooser, locate the directory where you want to place the
application EAR file, and in the File name field, type 2BonusApp.

LESSON 3 COOPERATING ENTERPRISE BEANS


APRIL 18, 2000 51

• Click New Application.


• Click OK.

Create Web Component WAR File


Now, go through the steps to create the WAR file. These steps are outlined in Lesson 1 and
summarized below. With BonusApp selected,
• Select File.New Web Component from the menus at the top.
• Introduction: Read and Click Next
• War File General Properties: Specify BonusWar for the display name. Click Add, go
to the ClientCode directory, add BonusServlet.class, Click Next, go to the Client-
Code directory, add bonus.html, click Finish.
• War File General Properties: Click Next.
• Choose Component Type:. Make sure Describe a servlet is selected. Click Next.
• Component General Properties: Make the display name BonusServlet. Click Next.
• Skip Parameters. Click Next.
• Aliases: Specify BonusAlias for URL Mappings. Click Finish.
In the Inspecting window, select Web Context and specify BonusRoot.

Create EJB JAR for the Session and Entity Beans


In this lesson, you will put both the session and entity Beans in the same JAR file. To do this,
you first create the JAR file with only the session Bean in it, and then add the entity Bean to
that JAR file.

Create JAR with Session Bean


With BonusApp selected,
• Select File.New Enterprise Bean from the menus at the top.
• Introduction: Read and click Next.
• EJB JAR: Make sure BonusApp shows in the Enterprise Bean will go in field. Spec-
ify 2BeansJar as the display name. Click Add (the one next to the Contents window).
Toggle the directory so the Beans directory displays with its contents.
• Select Calc.class, Click Add.
• Select CalcBean.class. Click Add.
• Select CalcHome.class. Click Add.

LESSON 3 COOPERATING ENTERPRISE BEANS


52 APRIL 18, 2000

• Enterprise Bean JAR classes: Make sure you see Beans/Calc.class, Beans/Cal-
cHome.class, and Beans/CalcBean.class in the display.
• Click OK.
• EJB JAR: Click Next.
• General: Make sure Beans.CalcBean is the classname, Beans.CalcHome is the Home
interface, and Beans.Calc is the Remote interface. Enter CalcBean as the display
name. Click session and stateless. Click Next.
• Environment Entries: Click Next. This simple session Bean does not use properties
(environment entries).
• Enterprise Bean References: Click Next. The references are handled during deploy-
ment rather than here.
• Resource References: Click Next. This simple session Bean does not look up a data-
base or JavaMail session object.
• Security: Click Next. This simple session Bean does not use security roles.
• Transaction Management: Select Container-managed transactions (if it is not
already selected). In the list below make calcBonus, and getRecord required. This
means the container starts a new transaction before running these methods. The trans-
action commits just before the methods end. You can find more information on these
transaction settings in Chapter 6 of the Enterprise JavaBeans Developer's Guide. Click
Next.
• Review Settings: Click Finish.
• In the Local Applications window, select BonusApp. In the Inspecting window,
select JNDI names, give CalcBean the JNDI name of calcs, and press the Return key.

Add the Entity Bean


WIth 2BonusApp selected,
• Select File.New Enterprise Bean from the menus at the top.
• Introduction: Read and click Next.
• EJB JAR: Make sure 2BeansJar shows in the Enterprise Bean will go in field. This
setting will add the new Bean to the existing JAR file instead of putting the new Bean
in its own JAR file. Specify 2BeansJar as the display name. Click Add (the one next to
the Contents window). Toggle the directory so the Beans directory displays with its
contents.
• Select Bonus.class, Click Add.
• Select BonusBean.class. Click Add.
• Select BonusHome.class. Click Add.

LESSON 3 COOPERATING ENTERPRISE BEANS


53 APRIL 18, 2000

• Enterprise Bean JAR classes: Make sure you see Beans/Bonus.class, Beans/
BonusHome.class, and Beans/BonusBean.class in the display.
• Click OK.
• EJB JAR: Click Next.
• General: Make sure Beans.BonusBean is the classname, Beans.BonusHome is the
Home interface, and Beans.Bonus is the Remote interface. Enter BonusBean as the dis-
play name. Click Entity. Click Next.
• Entity Settings: Select Container managed persistence. In the window below,
check bonus and socsec. The primary key class is java.lang.String, and the pri-
mary key field name is socsec. Note that the primary key has to be a class type. Prim-
itive types are not valid for primary keys. Click Next.
• Environment Entries: Click Next. This simple entity Bean does not use properties
(environment entries).
• Enterprise Bean References: Click Next. This simple entity Bean does not reference
other enterprise Beans.
• Resource References: Click Next. This simple entity Bean does not look up a data-
base or JavaMail session object.
• Security: Click Next. This simple entity Bean does not use security roles.
• Transaction Management: Select Container-managed transactions (if it is not
already selected). In the list below make create, findByPrimaryKey, getBonus and
getSocSec required. This means the container starts a new transaction before running
these methods. The transaction commits just before the methods end. You can find
more information on these transaction settings in Chapter 6 of the Enterprise Java-
Beans Developer's Guide. Click Next.
• Review Settings: Click Finish.
• In the Local Applications window, select BonusApp. In the Inspecting window,
select JNDI names, give BonusBean the JNDI name of bonus and CalcBean the JNDI
name of calcs, and press the Return key.
Before the J2EE application can be deployed, you need to specify deployment settings for
the entity Bean and generate the SQL. Here is how to do it:
• In the Local Applications window, select BonusBean.
• In the Inspecting window, select Entity, and click the Deployment Settings button
to the lower right.
• In the Deployment Settings window, specify jdbc/Cloudscape (with a capital C on
Cloudscape) for the Database JNDI name, press Return, make sure the Create table
on deploy and Delete table on Deploy boxes are checked, and click Generate SQL
now.

LESSON 3 COOPERATING ENTERPRISE BEANS


54 APRIL 18, 2000

Note: If you get an error that the connection was refused, start the database as
described in Start the Platform and Tools (page 49).

• When the SQL generation completes, select the findByPrimaryKey method in the EJB
method box. To the right a SQL statement appears. It should read SELECT “socsec”
FROM “BonusBeanTable” WHERE “socsec”=?. The question mark (?) represents the
parameter passed to the findByPrimaryKey method.
• Click OK.

Verify and Deploy the J2EE Application


Before you deploy the application, it is a good idea to run the verifier. The verifier will pick
up errors in the application components such as missing enterprise Bean methods that the
compiler does not catch.

Verify
With BonusApp selected, choose Verifier from the Tools menu. In the dialog that pops up,
click OK. The window should tell you that all tests passed. That is, if you used the session
Bean code provided for this lesson. Close the verifier window because you are now ready to
deploy the application.

Note: In the Version 1.2 software you might get a tests app.WebURI error. This
means the deploy tool did not put a .war extension on the WAR file during WAR file cre-
ation. This is a minor bug and the J2EE application deploys just fine in spite of it.

Deploy
From the Tools menu, choose Deploy Application. A Deploy BonusApp dialog box pops
up. Verify that the Target Server selection is either localhost or the name of the host running
the J2EE server.
Do not check the Return Client Jar box. The only time you need to check this box is when
you use bean-managed persistence or deploy a stand-alone application for the client pro-
gram. This example uses a servlet and HTML page so this book should not be checked.
Checking this box creates a JAR file with deployment information needed by a stand-alone
application.
Click Next.

LESSON 3 COOPERATING ENTERPRISE BEANS


55 APRIL 18, 2000

Make sure the JNDI names show for calcs for CalcBean and bonus for BonusBean. If they
do not, type the JNDI names in yourself, and press the Return key.
Click Next.
Make sure the Context Root name shows BonusRoot. If it does not, type it in yourself and
press the Return key.
Click Next.
Click Finish to start the deployment. A dialog box pops up that displays the status of the
deployment operation. When it is complete, the three bars on the left will be completely
shaded as shown in Figure 15. When that happens, click OK.

Figure 15 Deploy Application

LESSON 3 COOPERATING ENTERPRISE BEANS


56 APRIL 18, 2000

Run the J2EE Application


The web server runs on port 8000 by default. To open the bonus.html page point your
browser to http://localhost:8000/BonusRoot/bonus.html, which is where the Deploy
tool put the HTML file.
Fill in a social security number and multiplier, and click the Submit button. BonusServlet
processes your data and returns an HTML page with the bonus calculation on it.
Bonus Calculation

Soc Sec retrieved: 777777777


Bonus Amount Retrieved: 200.0

If you supply the same social security number twice, you will see something similar to this:
Bonus Calculation

Soc Sec passed in: 777777777


Multiplier passed in: 2
Duplicate primary key

LESSON 3 COOPERATING ENTERPRISE BEANS


APRIL 18, 2000 57

Lesson 4
JavaServer Pages Technology

JavaServer Pages (JSP) technology that lets you put segments of servlet code directly
within a static HTML or XML page. When the JSP Page is executed, the application server
creates, compiles, loads, and runs a background servlet to execute the servlet code segments
and return an HTML page.
This lesson changes the WAR file from Lesson 3 Cooperating Enterprise Beans (page 43) to
use a JSP Page instead of BonusServlet.
• Create the JSP Page (page 58)
• Change bonus.html (page 62)
• Start the Platform and Tools (page 63)
• Remove the WAR File (page 63)
• Assemble New WAR FIle (page 63)
• Verify and Deploy the J2EE Application (page 64)
• Run the J2EE Application (page 66)
• More Information (page 67)

LESSON 4 JAVASERVER PAGES TECHNOLOGY


58 APRIL 18, 2000

Create the JSP Page


A JSP Page looks like an HTML page with servlet code segments embedded between vari-
ous forms of leading (<%) and closing (%>) JSP tags. There are no HttpServlet methods
such as init, doGet, or doPost. Instead, the code that would normally be in these methods
is embedded directly in the JSP Page using JSP scriptlet tags.
The following JSP Page (Bonus.jsp) is equivalent to BonusServlet from Lesson 3 Cooperat-
ing Enterprise Beans (page 43). A more detailed description of the JSP tags follows the code
listing. Note that JSP tags cannot be nested. For example, you cannot nest a JSP comment
tag within a JSP scriptlet tag.
<HTML>
<HEAD>
<TITLE>Bonus Calculation</TITLE>
</HEAD>
<%-- Comment
Scriptlet for import statements
<%@ indicates a jsp directive --%>
<%@ page import="javax.naming.*" %>
<%@ page import="javax.rmi.PortableRemoteObject" %>
<%@ page import="Beans.*" %>
<%-- Comment
Scriptlet to get the parameters,
convert string to Integer to int for bonus
calculation, and declare/initialize bonus
variable. <% indicates a jsp scriptlet --%>
<%! String strMult, socsec; %>
<%! Integer integerMult; %>
<%! int multiplier; %>
<%! double bonus; %>
<%
strMult = request.getParameter("MULTIPLIER");
socsec = request.getParameter("SOCSEC");
integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
bonus = 100.00;
%>
<%-- Comment
Scriptlet to look up session Bean --%>
<%
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
CalcHome homecalc = (CalcHome)
PortableRemoteObject.narrow(
objref, CalcHome.class);
%>

LESSON 4 JAVASERVER PAGES TECHNOLOGY


APRIL 18, 2000 59

<%-- Comment
Scriptlet to create session Bean,
call calcBonus method, and retrieve a database
record by the social security number
(primary key) --%>
<%
try {
Calc theCalculation = homecalc.create();
Bonus theBonus = theCalculation.calcBonus(
multiplier,
bonus,
socsec);
Bonus record = theCalculation.getRecord(socsec);
%>
<%-- Comment
HTML code to display retrieved data
on returned HTML page. --%>
<H1>Bonus Calculation</H1>
Social security number retrieved:
<%= record.getSocSec() %>
<P>
Bonus Amount retrieved: <%= record.getBonus() %>
<P>
<%-- Comment
Scriptlet to catch DuplicateKeyException --%>
<%
} catch (javax.ejb.DuplicateKeyException e) {
String message = e.getMessage();
%>
<%-- Comment
HTML code to display original data passed to JSP
on returned HTML page --%>
Social security number passed in: <%= socsec %>
<P>
Multiplier passed in: <%= strMult %>
<P>
Error: <%= message %>
<%-- Comment
Scriptlet to close try and catch block --%>
<%
}
%>
<%-- Comment
HTML code to close HTML body and page --%>
</BODY>
</HTML>

LESSON 4 JAVASERVER PAGES TECHNOLOGY


60 APRIL 18, 2000

Comments
The first seven lines of Bonus.jsp shows straight HTML followed by a JSP comment. JSP
comments are similar to HTML comments except they start with <%-- instead of <!--,
which is how they look in HTML. You can use either JSP or HTML comments in a JSP file.
HTML comments are sent to the client’s web browser where they appear as part of the
HTML page, and JSP comments are stripped out and do not appear in the generated HTML.

Note: I found that putting a colon in a JSP comment as in <%-- Comment: Scriptlet
for import statements . . . created a runtime error that went away when I took
the colon out.

<HTML>
<HEAD>
<TITLE>Bonus Calculation</TITLE>
</HEAD>
<%-- Comment
Scriptlet for import statements
<%@ indicates a jsp directive --%>

Directives
JSP directives are instructions processed by the JSP engine when the JSP Page is translated
to a servlet. The directives used in this example tell the JSP engine to include certain pack-
ages and classes. Directives are enclosed by the <%@ and %> directive tags.
<%@ page import="javax.naming.*" %>
<%@ page import="javax.rmi.PortableRemoteObject" %>
<%@ page import="Beans.*" %>

Declarations
JSP declarations let you set up variables for later use in expressions or scriptlets. You can
also declare variables within expressions or scriptlets at the time you use them. The scope is
the entire JSP Page, so there is no concept of instance variables. That is, you do not have to
declare instance variables to be used in more than one expression or scriptlet. Declarations
are enclosed by the <%! and %> declaration tags. You can have multiple declarations. For
example, <%! double bonus; String text; %>.
<%! String strMult, socsec; %>
<%! Integer integerMult; %>
<%! int multiplier; %>
<%! double bonus; %>

LESSON 4 JAVASERVER PAGES TECHNOLOGY


APRIL 18, 2000 61

Scriptlets
JSP scriptlets let you embed java code segments into the JSP page. The embedded code is
inserted directly into the generated servlet that executes when the page is requested. This
scriptlet uses the variables declared in the directives described above. Scriptlets are enclosed
by the <% and %> scriptlet tags.
<%
strMult = request.getParameter("MULTIPLIER");
socsec = request.getParameter("SOCSEC");
integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
bonus = 100.00;
%>

Predefined Variables
A scriptlet can use the following predefined variables: session, request, response, out, and
in. This example uses the request predefined variable, which is an HttpServletRequest
object. Likewise, response is an HttpServletResponse object, out is a PrintWriter
object, and in is a BufferedReader object.
Predefined variables are used in scriptlets in the same way they are used in servlets, except
you do not declare them.
<%
strMult = request.getParameter("MULTIPLIER");
socsec = request.getParameter("SOCSEC");
integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
bonus = 100.00;
%>

Expressions
JSP expressions let you dynamically retrieve or calculate values to be inserted directly into
the JSP Page. In this example, an expression retrieves the social security number from the
Bonus entity Bean and puts it on the JSP page.

<H1>Bonus Calculation</H1>
Social security number retrieved:
<%= record.getSocSec() %>
<P>
Bonus Amount retrieved: <%= record.getBonus() %>
<P>

LESSON 4 JAVASERVER PAGES TECHNOLOGY


62 APRIL 18, 2000

JSP-Specific Tags
The JavaServer Pages 1.1 specification defines JSP-specific tags that let you extend the JSP
implementation with new features and hide a lot of complexity from visual designers who
need to look at the JSP page and modify it. The JSP example in this lesson does not use any
JSP-specific tags, but you will see an example of these tags in the next lesson.
The JSP-specific tags defined in the 1.1 specification are the following:
jsp:forward and jsp:include to instruct the JSP engine to switch from the current page to
another JSP page.
jsp:useBean, jsp:setProperty, and jsp:getProperty let you embed and use JavaBeans
technology inside a JSP Page.
jsp:plugin automatically downloads the appropriate Java Plug-In to the client to execute an
applet with the correct Java platform.

Change bonus.html
The only change you need to make to bonus.html is to have the ACTION parameter in the
HTML form invoke Bonus.jsp instead of BonusServlet.
<HTML>
<BODY BGCOLOR = "WHITE">
<BLOCKQUOTE>
<H3>Bonus Calculation</H3>
<FORM METHOD="GET" ACTION="Bonus.jsp">
<P>
Enter social security Number:
<P>
<INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT>
<P>
Enter Multiplier:
<P>
<INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT>
<P>
<INPUT TYPE="SUBMIT" VALUE="Submit">
<INPUT TYPE="RESET">
</FORM>
</FORM>
</BLOCKQUOTE>
</BODY>
</HTML>

LESSON 4 JAVASERVER PAGES TECHNOLOGY


63 APRIL 18, 2000

Start the Platform and Tools


To run this example, you need to start the J2EE server, the Deploy tool, and Cloudscape
database. In different windows, type the following commands:
j2ee -verbose
deploytool
cloudscape -start

If that does not work, type this from the J2EE directory:

Unix
j2sdkee1.2/bin/j2ee -verbose
j2sdkee1.2/bin/deploytool
j2sdkee1.2/bin/cloudscape -start

Windows
j2sdkee1.2\bin\j2ee -verbose
j2sdkee1.2\bin\deploytool
j2sdkee1.2\bin\cloudscape -start

Remove the WAR File


Click the BonusApp icon in the Local Applications window so you can see its application
components.
Select BonusWar so it is outlined and highlighted.
At the top of the Deploy tool, there is an Edit menu. Select Delete.

Assemble New WAR FIle


Before you can redeploy the J2EE application with the changes for this lesson, you have to
uninstall the Lesson 3 J2EE application. You can do this any time before you deploy, but just
to make sure you do not forget, do it now.

Uninstall the Application


At the bottom of the Deploy tool is a window listing BonusApp with an Uninstall button to
the right. Click Uninstall.

LESSON 4 JAVASERVER PAGES TECHNOLOGY


64 APRIL 18, 2000

Create Web Component WAR File


Now, go through the steps to create the WAR file.
• Select File.New Web Component from the menus at the top.
• Introduction: Read and Click Next.

Note: There appears to be a bug in the Deploy tool. Make sure you add Bonus.jsp first
followed by bonus.html. If you add bonus.html first, Deploy tool puts bonus.html
where Bonus.jsp should go, and Bonus.jsp where bonus.html should go. If this hap-
pens, you can manually fix the problem by copying them to their correct locations.
This is where they correctly belong after deployment:
~/j2sdkee1.2/public_html/JSPRoot/bonus.html
~/j2sdkee1.2/public_html/JSPRoot/WEB-INF/classes/Bonus.jsp

• War File General Properties: Specify BonusWar for the display name. Click Add, go
to the ClientCode directory, add Bonus.jsp, Click Next, go to the ClientCode direc-
tory, add bonus.html, click Finish.

Note: There appears to be a bug in the Deploy tool. If you Click Next on the War File
General Properties window, select Describe a JSP, and click Next, you get the fol-
lowing error: No jsp files could be found in the content files. Go back to add the
needed file. So, instead of Clicking Next on the War File General Properties win-
dow, Click Add again and add Bonus.jsp a second time. Click Finish.

• War File General Properties: Click Next.


• Choose Component Type:. Make sure Describe a JSP is selected. Click Next.
• Component General Properties: Make the display name BonusJSP. Click Finish.
In the Inspecting window, select Web Context and specify JSPRoot.

Verify and Deploy the J2EE Application


Before you deploy the application, it is a good idea to run the verifier. The verifier will pick
up errors in the application components such as missing enterprise Bean methods that the
compiler does not catch.

Verify
With BonusApp selected, choose Verifier from the Tools menu. In the dialog that pops up,
click OK. The window should tell you that all tests passed. That is, if you used the session

LESSON 4 JAVASERVER PAGES TECHNOLOGY


65 APRIL 18, 2000

Bean code provided for this lesson. Close the verifier window because you are now ready to
deploy the application.

Note: In the Version 1.2 software you might get a tests app.WebURI error. This
means the deploy tool did not put a .war extension on the WAR file during WAR file cre-
ation. This is a minor bug and the J2EE application deploys just fine in spite of it.

Deploy
From the Tools menu, choose Deploy Application. A Deploy BonusApp dialog box pops
up. Verify that the Target Server selection is either localhost or the name of the host running
the J2EE server.
Do not check the Return Client Jar box. The only time you need to check this box is when
you deploy a stand-alone application for the client program. This example uses an HTML
and JSP page so this book should not be checked. Checking this box creates a JAR file with
deployment information needed by a stand-alone application.
Click Next.
Make sure the JNDI names show calcs for CalcBean and bonus for BonusBean. If they do
not show these names, type them in yourself, and press the Return key.
Click Next.
Make sure the Context Root name shows JSPRoot. If it does not, type it in yourself and press
the Return key.
Click Next.
Click Finish to start the deployment. A dialog box pops up that displays the status of the
deployment operation. When it is complete, the three bars on the left will be completely
shaded as shown in Figure 16. When that happens, click OK.

LESSON 4 JAVASERVER PAGES TECHNOLOGY


66 APRIL 18, 2000

Figure 16 Deploy Application

Run the J2EE Application


The web server runs on port 8000 by default. To open the bonus.html page point your
browser to http://localhost:8000/JSPRoot/bonus.html, which is where the Deploy
tool put the HTML file.
Fill in a social security number and multiplier, and click the Submit button. Bonus.jsp pro-
cesses your data and returns an HTML page with the bonus calculation on it.
Bonus Calculation

Social Security number retrieved: 777777777


Bonus Amount Retrieved: 200.0

If you supply the same social security number twice, you will see something similar to this:

LESSON 4 JAVASERVER PAGES TECHNOLOGY


67 APRIL 18, 2000

Bonus Calculation

Soc Sec passed in: 777777777


Multiplier passed in: 2
Error: Duplicate primary key

More Information
Another way to use JavaServer pages technology is in combination with JavaBeans tech-
nology where the JSP page presents a form to the user and calls on the JavaBean to process
the data entered on the form. You can see an example at the following URL: http://
java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/Client.fm.html#10649

This next URL takes you to an article with a great explanation of JavaServer pages and Java-
Beans technologies: Building Your own JSP Components
http://developer.iplanet.com/viewsource/fields_jspcomp/fields_jspcomp.html

LESSON 4 JAVASERVER PAGES TECHNOLOGY


68 APRIL 18, 2000

LESSON 4 JAVASERVER PAGES TECHNOLOGY


APRIL 18, 2000 69

Lesson 5
Adding JavaBeans Technology
to the Mix

You can use JavaBeans technology to put a JavaBean between the JSP page and CalcBean
session Bean to get a better Model, View, Controller (MVC) separation. MVC is a design
pattern that consists of three kinds of objects. The Model provides the application business
logic, the View is its screen presentation, and the Controller is an object that manages what
happens when the user interacts with the View. A design pattern describes a recurring prob-
lem and its solution where the solution is never exactly the same for every recurrence.
Lesson 4 JavaServer Pages Technology (page 57) is set up so the HTML and JSP pages pro-
vide the screen presentation (View) and manage what happens when the user interacts with
the data (Controller). The entity and session Bean (BonusBean and CalcBean) are the appli-
cation objects or Model.
This lesson used a JSP page for the screen presentation (View), a JavaBean to manage what
happens when the user interacts with the View (Controller), and the entity and session Beans
for the application objects (Model). Separating the Controller from the View like this gives
lets the JavaBean serve as a wrapper for the session Bean and gives the example a much
cleaner MVC separation. An application that uses clear design patterns is easier to update,
maintain, and manage.
• About the Example (page 70)
• Create bonus.jsp (page 72)
• Create the JavaBeans Class (page 75)
• Bean Properties (page 77)
• Remove the WAR File (page 81)
• Assemble New WAR FIle (page 81)
• Verify and Deploy the J2EE Application (page 81)
• Run the J2EE Application (page 83)
• More Information (page 83)

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


70 APRIL 18, 2000

About the Example


In Lesson 4 JavaServer Pages Technology (page 57), the application user interface consisted
of an HTML page with an HTML form. The HTML form calls the JSP page when the user
clicks the Submit button on the HTML page.
Another way to create the user interface is with one JSP page that includes the HTML form,
JSP scriptlets, and JSP-specific tags for interacting with the JavaBean. When the JSP page
loads, the HTML form is displayed and the scriptlet and JSP-specific tags for interacting
with the JavaBean are executed. Because no data has been supplied yet, the display looks
like Figure 17:

Figure 17 When bonus.jsp Loads

After the user enters some data and clicks the Submit button, the HTML form is redisplayed
and the scriptlet and JSP-specific tags for interacting with the JavaBean execute again with
the data supplied. The display looks something like Figure 18. This is because the ACTION
parameter for the HTML form on bonus.jsp recursively calls itself.

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


APRIL 18, 2000 71

Figure 18 After User Enters Data and Clicks Submit

If the user enters the same social security number, a duplicate key error is returned and dis-
played on the JSP page as shown in Figure 19.

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


72 APRIL 18, 2000

Figure 19 Duplicate Key Error

Create bonus.jsp
The code for bonus.jsp is fairly straight forward because the code to look up the session
Bean and calculate the bonus is now in the JavaBean. The first part of the file contains the
HTML code to create the form. The code to pass the HTML form data to the JavaBean is in
the second part of the file. The complete bonus.jsp file appears below. Look it over before
going on to the discussion of its scriptlet and JSP-specific tags for interacting with the Java-
Bean.
<HTML>
<BODY BGCOLOR = "WHITE">
<HEAD>
<TITLE>Bonus Calculation</TITLE>
</HEAD>

<BLOCKQUOTE>
<H3>Bonus Calculation</H3>

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


APRIL 18, 2000 73

<!--ACTION parameter calls this page-->


<FORM METHOD="GET" ACTION="bonus.jsp">

<P>
Enter social security Number:
<P>
<INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT>
<P>

Enter Multiplier:
<P>
<INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT>

<P>
<INPUT TYPE="SUBMIT" VALUE="Submit">
<INPUT TYPE="RESET">
</FORM>

<!--Scriptlet and JavaBeans Tags start here -->


<jsp:useBean id = "jbonus" class = "JBonusBean"/>

<%! String sMult, ssec; %>


<%
sMult = request.getParameter("MULTIPLIER");
ssec = request.getParameter("SOCSEC");
%>

<jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/>


<jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/>

Social security number retrieved:


<jsp:getProperty name="jbonus" property="socsec"/>

<P>
Bonus Amount retrieved:
<jsp:getProperty name="jbonus" property="bonusAmt"/>

<P>
Error messages:
<jsp:getProperty name = "jbonus" property="message"/>

</BLOCKQUOTE>
</BODY>
</HTML>

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


74 APRIL 18, 2000

Specify the JavaBean


The following HTML tag specifies the JavaBean being used in this example. The id param-
eter defines an alias to use to reference the JavaBean, and the class parameter specifies the
JavaBeans class. In this example the id is jbonus and the class is JBonusBean.
<jsp:useBean id = "jbonus" class = "JBonusBean"/>

Get the Data


The following JSP scriptlets retrieve the user-supplied data from the HTML form input
fields. The multiplier is stored in the sMult String variable, and the social security number
is stored in the ssec String variable.
<%! String sMult, ssec; %>
<%
sMult = request.getParameter("MULTIPLIER");
ssec = request.getParameter("SOCSEC");
%>

Pass the Data to the JavaBean


The following HTML tags set two properties in the JavaBean. A property is a private field in
the JavaBean class. The first line uses the jsp:setProperty name tag to set the strMult
field in the JBonusBean class (aliased by the jbonus id) to the value stored in the sMult
variable. The second line performs a similar operation for the socsec field in the JBonus-
Bean class.

<jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/>


<jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/>
The value="<%=ssec%>" expression sends the data contained in the ssec vari-
able to the socsec field in the JavaBean.

Retrieve Data from the JavaBean


Retrieving data from a JavaBean is similar to sending data to it. You use the jsp:getProp-
erty name tag and indicate the property (private field) whose data you want to get. The fol-
lowing getProperty name tag retrieves the data stored in the socsec private field of the
JBonusBean class (aliased by the jbonus id).

Social security number retrieved:


<jsp:getProperty name="jbonus" property="socsec"/>
The following tags perform similar operations for the bonusAmt and message fields in the
JBonusBean class.

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


75 APRIL 18, 2000

<P>
Bonus Amount retrieved:
<jsp:getProperty name="jbonus" property="bonusAmt"/>

<P>
Error messages:
<jsp:getProperty name = "jbonus" property="message"/>

Create the JavaBeans Class


A JavaBeans class (or Bean for short) looks just like any ordinary Java programming
language class. But to be a Bean, a JavaBeans class must follow a set of simple naming and
design conventions as outlined in the JavaBeans specification. Because Beans follow the
JavaBeans specification, they can be accessed and managed by other programs and tools that
follow the same conventions.
In the Create bonus.jsp (page 72) section, HTML tags and JSP scriptlets are used to get and
set data in the private fields of the JBonusBean class. This is possible because the JBonus-
Bean class follows the JavaBeans naming and design conventions.

This section describes the JBonusBean code and gives you a very simple introduction to Jav-
aBeans technology as it is used with JSP pages. Visit the JavaBeans home page at http://
java.sun.com/beans/index.html for further information on JavaBeans technology.

Here is the JBonusBean class in its entirety. A discussion of its pertinent parts follows.
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import Beans.*;

public class JBonusBean {


private String strMult, socsec, message;
private double bonusAmt;
CalcHome homecalc;

public JBonusBean() {
try{
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc = (CalcHome)
PortableRemoteObject.narrow(
objref, CalcHome.class);
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


76 APRIL 18, 2000

}
public double getBonusAmt() {
if(strMult != null){
Integer integerMult = new Integer(strMult);
int multiplier = integerMult.intValue();
try {
double bonus = 100.00;
Calc theCalculation = homecalc.create();
Bonus theBonus = theCalculation.calcBonus(
multiplier, bonus, socsec);
Bonus record = theCalculation.getRecord(
socsec);
bonusAmt = record.getBonus();
socsec = record.getSocSec();
} catch (javax.ejb.DuplicateKeyException e) {
message = e.getMessage();
} catch (javax.ejb.CreateException e) {
e.printStackTrace();
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
return this.bonusAmt;
} else {
this.bonusAmt = 0;
this.message = "None.";
return this.bonusAmt;
}
}

public String getMessage(){


return this.message;
}
public String getSocsec(){
return this.socsec;
}
public String getStrMult(){
return this.strMult;
}
public void setSocsec(String socsec) {
this.socsec = socsec;
}
public void setStrMult(String strMult) {
this.strMult = strMult;
}
}

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


77 APRIL 18, 2000

Bean Properties
Properties define the data that a JavaBean makes accessible to other programs and tools
through get and set methods. The data might do things such as define the JavaBeans appear-
ance or behavior, or be used in or the result of a series of calculations and computations.
Properties are actually private class fields that should always be private and only accessible
through get and set methods.
The following code segment shows the private properties for the JBonusBean class. The
JBonusBean class has a corresponding get<property> method for each field and corre-
sponding set<property> methods for the strMult and socsec fields.
public class JBonusBean {
private String strMult, socsec, message;
private double bonusAmt;

Constructor
The JBonusBean constructor looks up the session Bean.
public JBonusBean() {
try{
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc = (CalcHome)
PortableRemoteObject.narrow(
objref, CalcHome.class);
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}
}

Set Methods
JBonusBean has two Setter methods (methods prefixed with the word set). Setter methods
set properties (private fields) to specified values. The two Setter methods are setSocsec and
setStrMult for setting the socsec and strMult private fields (JavaBean prop-
erties).

In this example, the values used to set the socsec and strMult properties come from the
setProperty name tags in the JSP page. The J2EE server uses the information supplied in
the following setProperty name tags to locate the corresponding set methods in the JBo-
nusBean (aliased by the jbonus id):

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


78 APRIL 18, 2000

<jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/>


<jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/>
In the JBonusBean class, the set<property> methods follow naming conventions so the
J2EE server can map the setProperty name tags in the JSP file to the correct set<prop-
erty> methods to pass the data from the JSP page to the JavaBean.

With Setter methods, the method name consists of the word set and the property name. The
property name is the name of one of the JBonusBean private fields. While field names begin
with a lowercase letter by convention, the second word in a method name is always capital-
ized. So to set the socsec private field, the method name is setSocsec. The J2EE server
maps the uppercase Socsec in the method name to the lowercase socsec field. Setter meth-
ods have no return value and have one argument of the appropriate type.
public void setSocsec(String socsec) {
this.socsec = socsec;
}
public void setStrMult(String strMult) {
this.strMult = strMult;
}

Get Methods
JBonusBean has four Getter methods (methods prefixed with the word get). Getter methods
get and return property values (private field values). The four Getter methods are getBo-
nusAmt, getMessage, getSocsec, and getStrMult for returning data from the bonusAmt,
message, socsec, and strMult private fields (JavaBean properties).

In this example, the values used to set the bonusAmt and message fields come from the get-
BonusAmt method. The JSP page retrieves data from the JBonusBean properties using the
following getProperty name tags. The JSP page retrieves only the values it is interested in,
so you might notice that although there is a JBonusBean property for the multiplier (the str-
Mult field), that value is not retrieved by the JSP page.

Social security number retrieved:


<jsp:getProperty name="jbonus" property="socsec"/>
<P>
Bonus Amount retrieved:
<jsp:getProperty name="jbonus" property="bonusAmt"/>

<P>
Error messages:
<jsp:getProperty name = "jbonus" property="message"/>

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


79 APRIL 18, 2000

Getter methods follow the same naming conventions as Setter methods so the JSP page can
retrieve data from the JBonusBean.Getter methods always have a return value and no argu-
ments. You might notice that although the getBonusAmt method sets property values and
does not really need to return a value in this example, it returns this.bonusAmt to avoid a
runtime J2EE server error.
The getBonusAmt method uses an if-else statement to handle the case where no strMult
value is supplied. When the JSP page is first loaded, the end user has not supplied any data,
but all tags and scriptlets on the page are executed anyway. In this event, the data value for
the strMult property passed to JBonusBean is null, which results in a null multiplier and a
null bonusAmt value. A runtime server error occurs when the JSP page gets and tries to dis-
play the null bonusAmt value. To prevent this runtime error, bonusAmt is set to 0 in the event
a null strMult value is received from the JSP page.
public double getBonusAmt() {
if(strMult != null){
Integer integerMult = new Integer(strMult);
int multiplier = integerMult.intValue();
try {
double bonus = 100.00;
Calc theCalculation = homecalc.create();
Bonus theBonus = theCalculation.calcBonus(
multiplier, bonus, socsec);
Bonus record = theCalculation.getRecord(
socsec);
bonusAmt = record.getBonus();
socsec = record.getSocSec();
} catch (javax.ejb.DuplicateKeyException e) {
message = e.getMessage();
} catch (javax.ejb.CreateException e) {
e.printStackTrace();
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
return this.bonusAmt;
} else {
this.bonusAmt = 0;
this.message = "None.";
return this.bonusAmt;
}
}
public String getMessage(){

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


80 APRIL 18, 2000

return this.message;
}
public String getSocsec(){
return this.socsec;
}
public String getStrMult(){
return this.strMult;
}
public void setSocsec(String socsec) {
this.socsec = socsec;
}
public void setStrMult(String strMult) {
this.strMult = strMult;
}

Start the Platform and Tools


To run this example, you need to start the J2EE server, the Deploy tool, and Cloudscape
database. In different windows, type the following commands:
j2ee -verbose
deploytool
cloudscape -start

If that does not work, type this from the J2EE directory:

Unix
j2sdkee1.2/bin/j2ee -verbose
j2sdkee1.2/bin/deploytool
j2sdkee1.2/bin/cloudscape -start

Windows
j2sdkee1.2\bin\j2ee -verbose
j2sdkee1.2\bin\deploytool
j2sdkee1.2\bin\cloudscape -start

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


APRIL 18, 2000 81

Remove the WAR File


Click the BonusApp icon in the Local Applications window so you can see its application
components.
Select BonusWar so it is outlined and highlighted.
At the top of the Deploy tool, there is an Edit menu. Select Delete.

Assemble New WAR FIle


Before you can redeploy the J2EE application with the changes for this lesson, you have to
uninstall the Lesson 4 J2EE application. You can do this any time before you deploy, but just
to make sure you do not forget, do it now.

Uninstall the Application


At the bottom of the Deploy tool is a window listing BonusApp with an Uninstall button to
the right. Click Uninstall.

Create Web Component WAR File


Now, go through the steps to create the WAR file.
• Select File.New Web Component from the menus at the top.
• Introduction: Read and Click Next.
• War File General Properties: Specify BonusWar for the display name. Click Add. In
the next window, go to the ClientCode directory, add JBonusBean.class. Click Next,
go to the ClientCode directory, add bonus.jsp, click Finish.

Note: Make sure you add JBonusBean.class before you add bonus.jsp.

• War File General Properties: Click Next.


• Choose Component Type:. Make sure Describe a JSP is selected. Click Next.
• Component General Properties: Make the display name BonusJSP. Click Finish.
In the Inspecting window, select Web Context and specify JSPRoot.

Verify and Deploy the J2EE Application


Before you deploy the application, it is a good idea to run the verifier. The verifier will pick
up errors in the application components such as missing enterprise Bean methods that the
compiler does not catch.

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


82 APRIL 18, 2000

Verify
With BonusApp selected, choose Verifier from the Tools menu. In the dialog that pops up,
click OK. The window should tell you that all tests passed. That is, if you used the session
Bean code provided for this lesson. Close the verifier window because you are now ready to
deploy the application.

Note: In the Version 1.2 software you might get a tests app.WebURI error. This
means the deploy tool did not put a.war extension on the WAR file during WAR file cre-
ation. This is a minor bug and the J2EE application deploys just fine in spite of it.

Deploy
From the Tools menu, choose Deploy Application. A Deploy BonusApp dialog box pops
up. Verify that the Target Server selection is either localhost or the name of the host running
the J2EE server.
Do not check the Return Client Jar box. The only time you need to check this box is when
you deploy a stand-alone application for the client program. This example uses a JSP page
and JavaBean so this book should not be checked. Checking this box creates a JAR file with
deployment information needed by a stand-alone application.
Click Next.
Make sure the JNDI names show calcs for CalcBean and bonus for BonusBean. If they do
not show these names, type them in yourself, and press the Return key.
Click Next.
Make sure the Context Root name shows JSPRoot. If it does not, type it in yourself and press
the Return key.
Click Next.
Click Finish to start the deployment. A dialog box pops up that displays the status of the
deployment operation. When it is complete, the three bars on the left will be completely
shaded as shown in Figure 20. When that happens, click OK.

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


APRIL 18, 2000 83

Figure 20 Deploy Application

Run the J2EE Application


The web server runs on port 8000 by default. To open the bonus.jsp page point your
browser to http://localhost:8000/JSPRoot/bonus.jsp, which is where the Deploy tool
put the JSP page.
Fill in a social security number and multiplier, and click the Submit button. BonusServlet
processes your data and returns an HTML page with the bonus calculation on it. See About
the Example (page 70) for screen captures showing the application in action.

More Information
Visit the JavaBeans home page at http://java.sun.com/beans/index.html for further
information on JavaBeans technology.

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


84 APRIL 18, 2000

LESSON 5 ADDING JAVABEANS TECHNOLOGY TO THE MIX


APRIL 18, 2000 85

Lesson 6
Extensible Markup Language
(XML)

eXtensible Markup Language (XML) is a language for representing and describing text-
based data so the data can be read and handled by any program or tool that uses XML APIs.
Programs and tools can generate XML files that other programs and tools can read and han-
dle. For example, a company might use XML to product reports so different parties who
receive the reports can handle the data in a way that best suits their needs. One party might
put the XML data through a program to translate the XML to HTML so it can post the
reports to the web, another party might put the XML data through a tool to produce a stock-
holder booklet, and yet another party might put the XML data through a tool to create a mar-
keting presentation. Same data, different needs, and an array of platform-independent
programs and tools to use the same data in any number of different ways.
These highly flexible capabilities are available through XML tags, Document Type Defini-
tions (DTDs) also known as XML schemas, and XML APIs. This lesson adapts the example
from Lesson 5 Adding JavaBeans Technology to the Mix (page 69) so the JavaBean class
uses XML APIs to print a simple report where the data is marked with XML tags.
• Marking and Handling Text (page 86)
• Change the JavaBean Class (page 86)
• The APIs (page 91)
• Assemble, Verify, Deploy, and Run (page 92)
• More Information (page 92)

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


86 APRIL 18, 2000

Marking and Handling Text


With XML you define markup tags to represent the different elements of data in a text file.
For example, if you have a text file that consists of a short article, you define XML tags to
represent the title, author, first level heads, second level heads, bullet lists, article text, and so
on. Once the data is represented by XML tags, you can create a Document Type Definition
(DTD) and/or eXtensible Style sheet Language (XSL) file to describe how you want the data
handled.
• XSL styles let you do things like map XML to HTML. For example, you can define an
XML title tag to represent the title of an article, and create an XSL file that maps the
XML title tag to the HTML H1 heading tag for display to the end user.
• A DTD (also known as an XML schema) contains specifications that allow other pro-
grams to validate the structure of an XML file to ensure the tagged data is in the correct
format. For example, a DTD for an article might allow one title tag, but zero or more
first and second level heads.
Any program capable of parsing XML can check for well-formed XML tags, and any pro-
gram capable of applying XSL styles or DTD specifications to XML data can handle the
tagged data intelligently. For example, if an article has two title tags, but the DTD allows
only one, the program returns an error. Checking an XML document against a DTD is what
is known as verification.
The nice thing about XML is the tagging is separate from the style sheet and DTD. This
means you can have one XML document and one to many style sheets or DTDs. Different
style sheets let you have a different presentation depending on how the document is used.
For example, an article on XML can have a style sheet for the different web sites where it is
to be published so it will blend with the look and feel of each site.
The current J2EE release does not have an eXtensible Style sheet Language Transformation
(XSLT) engine so it is not currently possible to use a style sheet to do things such as trans-
form an XML document into HTML for display.

Change the JavaBean Class


In this lesson, a genXML method is added to the JBonusBean class to generate the XML doc-
ument shown below. A description of the code to generate this file comes after the discussion
here of the XML document tags and structure.
<?xml version="1.0"?>
<report>
<bonusCalc ssnum="777777777" bonusAmt="300.0" />
</report>

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


APRIL 18, 2000 87

XML Prolog
The <?xml version=”1.0”?> line is the XML prolog. An XML file should always start with
a prolog that identifies the document as an XML file. The prolog is not required and is read
only by humans, but it is good form to include it. Besides version information, the prolog
can also contain encoding and standalone information.
• Encoding information: indicates the character set used to encode the document data.
Uncompressed Unicode is shown as <?xml version=”1.0” encoding=”UTF-8”?>.
The Western European and English language character set is indicated by:
<?xml version=”1.0” encoding=”ISO-8859-1”?>.
• Standalone information: indicates if this document uses information in other files.
For example, an XML document might rely on a style sheet for information on how to
create the user interface in HTML, or a DTD for valid tag specifications.

Document Root
The <report> tag is the first XML tag in this file. It is the top-level XML tag and marks the
beginning of the document data. Another name for this level tag is root. XML tags have a
matching end tag, so the end of this document has the corresponding </report> tag to close
the pair.
You can give XML tags any name you want. This example uses report because the XML
file is a bonus report. It could just as well be named <root> or <begin> or whatever. The
name takes on meaning in the style sheet and DTD because that is where you assign specifi-
cations to tags by their names.

Child Nodes
The <bonusCalc> tag represents the bonus report. This tag is a child node that is added to
the root. It uses attributes to specify the social security number and bonus amount values
(ssnum and bonusAmt). You can define a DTD to check that the bonusCalc tag has the ssnum
attribute and bonusAmt attributes and have your program raise an error if an attribute is miss-
ing or if attributes are present that should not be there.
<bonusCalc ssnum="777777777" bonusAmt="300.0" />

Other XML Tags


There are a number of ways to tag data. This example uses empty tags, which are tags that
do not enclose data, use attributes to specify data, and are closed with a slash. The following
empty tag from this example, could be created so the data is enclosed by XML tags instead.
The XML parser checks that all data enclosed by data has what are called well-formed tags.
Well-formed tags consist of an opening tag and a closing tag as shown in the well-formed tag
example below.

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


88 APRIL 18, 2000

Empty tag:
<bonusCalc ssnum="777777777" bonusAmt="300.0" />

Well-formed tags:
<bonusCalc>
<ssnum>"777777777"</ssnum>
<bonusAmt>300.0</bonusAmt>
</bonusCalc>

XML comment tags look just like HTML comment tags.


<!-- Bonus Report -->
<bonusCalc ssnum="777777777" bonusAmt="300.0" />

Processing Instructions give commands or information to an application that is processing


the XML data. Processing instructions have the format <? target instructions?> where
target is the name of the application doing the processing, and instructions embodies the
information or commands for the application to process. The prolog is an example of a pro-
cessing instruction, where xml is the target and version=”1.0” embodies the instructions.
Note that the target name xml is reserved for XML standards.
<?xml version=”1.0”?>
You can also use processing instructions to do things like distinguish between different ver-
sions of a presentation such as the high-level executive version and the technical version.

JavaBean Code
The JBonusBean class for this lesson has import statements for creating the XML document,
handling errors, and writing the document out to the terminal. This lesson writes the XML
output to the terminal to keep things simple. The XML output could just as well be written to
a file, but you would need to configure your browser to use Java Plug-In and include a secu-
rity policy file granting the JavaBean code permission to write to the file.
To generate the XML file for this lesson, you need to import the ElementNode and XmlDocu-
ment classes. You also need the StringWriter and IOException classes to write the XML
data to the terminal.
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import Beans.*;
import java.io.StringWriter;
import java.io.IOException;
import com.sun.xml.tree.ElementNode;
import com.sun.xml.tree.XmlDocument;

This version of the JBonusBean class has one more instance variables. The session Bean’s
remote interface, theCalculation, needs to be accessed from the getBonusAmt and genXML
methods. This is because genXML reads the database to generate XML for all records stored
in the database and has to be able to access the session Bean’s getRecord method.

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


APRIL 18, 2000 89

Calc theCalculation;

The JBonusBean.genXML method is called from the getBonusAmt method after the process-
ing completes in the event strMult is not null. The first thing this method does is create an
XMLDocument object and the root node, and adds the root to the document. The root node
represents the top-level point in the document hierarchy (or tree) and is the point at which
processing begins.
private void genXML(){
Bonus records = null;
//Create XML document
XmlDocument doc = new XmlDocument();
//Create node
ElementNode root = (ElementNode)
doc.createElement("report");
//Add node to XML document
doc.appendChild(root);

The try and catch block that comes next, gets the record out of the database, retrieves the
bonus amount and social security number from the record, converts the bonus amount to a
string, creates a child node (bonusCalc), and adds the social security number and bonus
amount to the bonusCalc child node as attributes. The child node represents the second
level in the document hierarchy or tree, and the attributes represent the third level.
try{
//Get database record
records = theCalculation.getRecord(socsec);
//Retrieve the social security number from record
String ssRetrieved = records.getSocSec();
//Retrieve bonus amount from record
double bRetrieved = records.getBonus();
//Convert double to string
Double bonusObj = new Double(bRetrieved);
String bString = bonusObj.toString();
//Create child node
ElementNode bonusCalc = (ElementNode)
doc.createElement("bonusCalc");
//Add attributes to child node
bonusCalc.setAttribute("ssnum", ssRetrieved);
bonusCalc.setAttribute("bonusAmt", bString);
//Add child node to root
root.appendChild(bonusCalc);
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}

The last part of the genXML method creates a StringWriter object, writes the document
hierarchy or tree to the StringWriter object, and writes the StringWriter object to the ter-
minal.

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


90 APRIL 18, 2000

try{
StringWriter out = new StringWriter();
doc.write(out);
System.out.println(out);
} catch (java.io.FileNotFoundException fe) {
System.out.println("Cannot write XML");
} catch (IOException ioe) {
System.out.println("cannot write XML");
}

The hierarchy or tree structure for the XML document is called the Document Object Model
(DOM). Figure 21 shows a simplified representation of the DOM for this lesson’s example.
The API calls in the genXML method create the DOM and you can make API calls to access
the DOM to do such things as add, delete, and edit child nodes, or validating the DOM
against a DTD. You can also create or a DOM from an XML file.

Document Root
report

Child Node
bonusCalcs

Social Security Number Attribute Bonus Amount Attribute


ssnum bonusAmt

Figure 21 Document Object Model (DOM)

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


APRIL 18, 2000 91

The APIs
The j2ee.jar file that comes with your J2EE installation provides APIs for parsing and
manipulating XML data. The JAR file currently provides SAX, DOM, and J2EE XML APIs.
You can use whichever API best suits your needs because as shown in Figure 22, XML text
is independent of the platform and language of its creation..

DTD

Application written in XML Application written in


Java programming DOM SAX C++ running on
language running on Windows.
Unix. HTTP

Figure 22 Platform and Language Neutral Text

SAX and DOM


The SAX API is an event-driven, serial-access mechanism that does element by element pro-
cessing.
The DOM API provides a relatively familiar tree structure of objects, and is a little easier to
use than the SAX API. You can use the DOM API to manipulate the hierarchy of application
objects it encapsulates. The DOM API is ideal for interactive applications because the entire
object model is present in memory, where it can be accessed and manipulated by the user.
On the other hand, constructing the DOM requires reading the entire XML structure and
holding the object tree in memory, so it is much more CPU and memory intensive. For that
reason, the SAX API will tend to be preferred for server-side applications and data filters
that do not require an in-memory representation of the data.

Note: You can find more information on the DOM and SAX APIs at this location:
http://java.sun.com/xml/docs/tutorial/overview/3_apis.html

J2EE
The platform-independent J2EE XML APIs use a DOM tree and provide a wealth of meth-
ods for manipulating the DOM hierarchy. The J2EE XML APIs are in the package com.sun
and were used in this lesson’s example. Please note that these APIs are subject to change.

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


92 APRIL 18, 2000

Assemble, Verify, Deploy, and Run


The instructions for assembling, verifying, deploying, and running this example are exactly
the same as they are for Lesson 5 Adding JavaBeans Technology to the Mix (page 69) begin-
ning with Remove the WAR File (page 81).

More Information
There is a lot of information about XML on the Web that you can access with a good search
engine. A very good web site is www.xml.com. The java.sun.com site has an XML tutorial
at http://java.sun.com/xml/docs/tutorial/index.html.

LESSON 6 EXTENSIBLE MARKUP LANGUAGE (XML)


APRIL 18, 2000 93

Lesson 7
JDBC Technology and Bean-
Managed Persistence

Up to this point, the example J2EE application has written data to and read data from the
underlying Cloudscape database without your writing and SQL code. This is because the
container has been handling data storage and retrieval on behalf of the enterprise Bean. Con-
tainer-managed persistence is the term used to describe the situation where the container
handles data storage and retrieval. This lesson shows you how to override the default con-
tainer-managed persistence and use what is called bean-managed persistence.
Bean-managed persistence is when you override container-managed persistence and imple-
ment entity or session Bean methods to use the SQL commands you provide. Bean-managed
persistence can be useful if you need to improve performance or map data in multiple Beans
to one row in a database table.
This lesson changes the entity Bean in the example J2EE application from using container-
managed persistence to using bean-managed persistence.
• Bean Lifecycle (page 94)
• Change the BonusBean Code (page 95)
• Create the Database Table (page 101)
• Uninstall J2EE Application (page 103)
• Delete and Create EJB JAR File (page 103)
• Verify and Deploy the J2EE Application (page 106)
• Run the J2EE Application (page 107)
• More Information (page 108)

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


94 APRIL 18, 2000

Bean Lifecycle
The BonusBean (page 29) section in Lesson 3 shows the container-managed BonusBean
class. The only methods with implementations are getBonus to return the bonus value, get-
SocSec to return the social security number, and ejbCreate to create an entity Bean with the
bonus and socsec values passed to it. The container takes care of such things as creating a
row in the database table for the data, and ensuring the data in memory is consistent with the
data in the table row. With bean-managed persistence, you have to implement all of this
behavior yourself, which means adding JDBC and SQL code, and implementing the empty
methods in the container-managed example.
A session or an entity Bean consists of business methods and lifecycle methods. In the
example, CalcBean has two business methods, calcBean and getRecord, and BonusBean
has two business methods, getBonus and getSocsec. Both CalcBean and BonusBean have
the following lifecycle methods. Business methods are called by clients and lifecycle meth-
ods are called by the Bean’s container.
setEntityContext: The container calls this method first to pass an entity context object to
the entity Bean. The entity context is dynamically updated by the container so even if the
entity Bean is invoked by many clients over its lifetime, the context contains current data for
each invocation. A session Bean has a corresponding setSessionContext method that per-
forms a similar function as the setEntityContext method.
ejbCreate: The container calls this method when a client calls a create method in the Bean’s
home interface. For each create method in the home interface, the Bean has a corresponding
ejbCreate method with the same signature (parameters and return value).

ejbPostCreate: The container calls this method after it calls the ejbCreate method com-
pletes. There is an ejbPostCreate method for every ejbCreate method that takes the same
arguments as its corresponding create method. However, ejbPostCreate has no return
value. Use ejbPostCreate to implement any special processing needed after the bean is cre-
ated, but before it becomes available to the client. Leave this method empty if no special pro-
cessing is needed.
ejbRemove: The container calls this method when a client calls a remove method in the
Bean’s home interface. The example J2EE application for this tutorial does not include a
remove method in the home interface.
unsetEntityContext: The container calls this method after the ejbRemove has been called
to remove the entity Bean from existence. Only entity Beans have an unsetEntityContext
method. A session Bean does not have a corresponding unsetSessionContext method.
ejbFindByPrimaryKey: The container calls this method when a client calls the findByPri-
maryKey method in the Bean’s home interface. For each find method in the home interface,
the Bean has a corresponding ejbFindXXX method with the same signature (parameters and
return value).
ejbLoad and ejbStore: The container calls these methods to synchronize the Bean’s state
with the underlying database. When a client sets or gets data in the Bean such as in the case

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 95

of a get method, the container calls ejbStore to send the object data to the database and
calls ejbLoad to read it back in again. When a client calls a find method, the container calls
ejbLoad to initialize the Bean with data from the underlying database.

ejbActivate and ejbPassivate: The container calls these methods to activate and passi-
vate the Bean’s state. Activation and passivation refer to swapping a Bean in and out of tem-
porary storage to free memory, which might a occur if a given Bean has not been called by a
client in a long time. Implementations for ejbPassivate might include things like closing
connections or files used by the Bean, and for ejbActivate might include things like
reopening those same connections or files.

Change the BonusBean Code


This section walks through the bean-managed persistence BonusBean code. The first thing
you will notice is that there is a lot more code here than for the container-managed persis-
tence version.

Import Statements
The InitialContext, DataSource, and Connection interfaces are imported for establishing
a connection to the database. The PreparedStatement interface is imported to be used as a
template to create a SQL request. The ResultSet interface is imported to manage access to
data rows returned by a query. The FinderException and SQLException classes are
imported to handle lookup and database access exceptions.
package Beans;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
iimport javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.ejb.FinderException;
import java.sql.SQLException;

Instance Variables
The instance variables added to this lesson let you establish and close database connections.
The string java:comp/env/jdbc/BonusDB indicates the resource reference name, which you
also specify when you add the entity Bean to the J2EE application using the Deploy tool. In
this example, the resource reference is an alias to the Cloudscape database (CloudscapeDB)
where the table data is stored.

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


96 APRIL 18, 2000

Later, you will create the BONUS table in the CloudscapeDB, and during deployment, you will
map jdbc/BonusDB to jdbc/CloudscapeDB.
public class BonusBean implements EntityBean {
private EntityContext context;
private Connection con;
private String dbName =
"java:comp/env/jdbc/BonusDB";
private InitialContext ic = null;
private PreparedStatement ps = null;
private double bonus;
private String socsec;

Business Methods
The business methods have not changed for this lesson except for calls to Sys-
tem.out.println, which let you see the order in which business and lifecycle methods are
called at runtime.
public double getBonus() {
System.out.println("getBonus");
return this.bonus;
}
public String getSocSec() {
System.out.println("getSocSec");
return this.socsec;
}

LifeCycle Methods
Calls to System.out.println, which let you see the order in which business and lifecycle
methods are called at runtime.

ejbCreate
The ejbCreate method signature for this lesson throws RemoteException and SQLException
in addition to CreateException. SQLException is needed because the ejbCreate method
for this lesson provides its own SQL code (it does not rely on the container to provide it),
and RemoteException is needed because this method performs remote access.
One thing to notice about this class is that it returns a String value which is the primary key,
but the declaration for this method in the home interface expects to receive a Bonus class
instance. The container uses the primary key returned by this method to create the Bonus
instance.
public String ejbCreate(double bonus, String socsec)
throws RemoteException,
CreateException, SQLException {
this.socsec=socsec;
this.bonus=bonus;

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 97

System.out.println("Create Method");
try {
//Establish database connection
ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL INSERT statement
//to insert into BONUS table
ps = con.prepareStatement(
"INSERT INTO BONUS VALUES (? , ?)");
//Set 1st PreparedStatement value marked by ? , with
//socsec and the 2nd value marked by ?) with bonus
ps.setString(1, socsec);
ps.setDouble(2, bonus);
ps.executeUpdate();
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} finally {
//Close database connection
ps.close();
con.close();
}
//Return primary key
return socsec;
}

ejbPostCreate
This method has the same signature as ejbCreate, but no implementation because this sim-
ple example performs no post create processing or initialization.
public void ejbPostCreate(double bonus,
String socsec)
throws RemoteException,
CreateException,
SQLException {
System.out.println("Post Create");
}

ejbFindByPrimaryKey
The container-managed version of BonusBean did not include an ejbFindByPrimaryKey
implementation because the container can locate database records by their primary keys if
you specify container-managed persistence and provide the primary key field during deploy-
ment. In this lesson, BonusBean is deployed with bean-managed persistence so you must
provide an implementation for this method and throw the SQLException. The container-
managed version throws RemoteException and FinderException only.
If the find operation locates a record with the primary key passed to ejbFindByPrimaryKey,
the primary key value is returned so the container can call the ejbLoad method to initialize
BonusBean with the retrieved bonus and socsec data.

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


98 APRIL 18, 2000

One thing to notice about this class is that it returns a String value which is the primary key,
but the declaration for this method in the home interface expects to receive a Bonus class
instance. The container uses the primary key returned by this method to create the Bonus
instance.
public String ejbFindByPrimaryKey(String primaryKey)
throws RemoteException,
FinderException, SQLException {
System.out.println("Find by primary key");
try {
//Establish database connection
ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL SELECT statement
//to select from BONUS table
ps = con.prepareStatement(
"SELECT socsec FROM BONUS WHERE socsec = ? ");
ps.setString(1, primaryKey);
//Use ResultSet to capture SELECT statement results
ResultSet rs = ps.executeQuery();
//If ResultSet has a value, the find was successful,
//and so initialize and return key
if(rs.next()) {
key = primaryKey;
} else {
System.out.println("Find Error");
}
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} finally {
//Close database connection
ps.close();
con.close();
}
//Return primary key
return key;
}

ejbLoad
This method is called after a successful call to ejbFindByPrimaryKey to load the retrieved
data and synchronize the Bean data with the database data.
public void ejbLoad() {
System.out.println("Load method");
try {
//Establish database connection
ic = new InitialContext();
DataSource ds = (DataSource) ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL SELECT statement
//to select from BONUS table

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 99

ps = con.prepareStatement(
"SELECT * FROM BONUS WHERE SOCSEC = ?");
ps.setString(1, this.socsec);
//Use ResultSet to capture SELECT statement results
ResultSet rs = ps.executeQuery();
//If ResultSet has a value, the find was successful
if(rs.next()){
this.bonus = rs.getDouble(2);
} else {
System.out.println("Load Error");
}
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} finally {
try {
//Close database connection
ps.close();
con.close();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
}
}
}

ejbStore
This method is called when a client sets or gets data in the Bean to send the object data to the
database and keep the Bean data synchronized with the database data.
public void ejbStore() {
System.out.println("Store method");
try {
//Establish database connection
DataSource ds = (DataSource)ic.lookup(dbName);
con = ds.getConnection();
//Use PreparedStatement to form SQL UPDATE statement
//to update BONUS table
ps = con.prepareStatement(
"UPDATE BONUS SET BONUS = ? WHERE SOCSEC = ?");
//Set 1st PreparedStatement value marked by ? with
//bonus and the 2nd value marked by ?) with socsec
ps.setDouble(1, bonus);
ps.setString(2, socsec);
int rowCount = ps.executeUpdate();
} catch (javax.naming.NamingException ex) {
ex.printStackTrace();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
} finally {
try {

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


100 APRIL 18, 2000

//Close database connection


ps.close();
con.close();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
}
}
}

ejbRemove
This method is called when a client calls a remove method on the Bean’s home interface.
The JavaBean client in this example does not provide a remove method that a client can call
to remove BonusBean from its container. Nevertheless, the implementation for an ejbRemove
method is shown here. When the container calls ejbRemove, ejbRemove gets the primary key
(socsec) from the socsec instance variable, removes the Bean from its container, and deletes
the corresponding database row.
public void ejbRemove()
throws RemoteException {
System.out.println("Remove method");
try {
DataSource ds = (DataSource)ic.lookup(dbName);
con = ds.getConnection();
ps = con.prepareStatement(
"DELETE FROM BONUS WHERE SOCSEC = ?");
ps.setString(1, socsec);
ps.executeUpdate();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
try {
ps.close();
con.close();
} catch (java.sql.SQLException ex) {
ex.printStackTrace();
}
}

ejbActivate
When a Bean has not been used in a long time, the container passivates it or moves it to tem-
porary storage where the container can be readily reactivate the Bean in the event a client
calls one of the Bean’s business methods. This method calls the getPrimaryKey method on
the entity context so the primary key is available to clients querying the bean. When a query
is made, the container uses the primary key to load the Bean data.
public void ejbActivate() {
System.out.println("Activate method");
socsec = (String)context.getPrimaryKey();
}

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 101

ejbPassivate
When a Bean has not been used in a long time, the container passivates it or moves it to tem-
porary storage where the container can be readily reactivate the Bean in the event a client
calls one of the Bean’s business methods. This method sets the primary key to null to free
memory while the Bean is in the passive state.
public void ejbPassivate() {
System.out.println("Passivate method");
socsec = null;
}

setEntityContext
This method is called by the container to initialize the Bean’s context instance variable.
This is needed because the ejbActivate method calls the getPrimarykey method on the
context instance variable to move a passive Bean to its active state.

public void setEntityContext(


javax.ejb.EntityContext ctx){
System.out.println("setEntityContext method");
this.context = ctx;
}

unsetEntityContext
This method is called by the container to set the context instance variable to null after the
ejbRemove method has been called to remove the entity Bean from existence. Only entity
Beans have an unsetEntityContext method.
public void unsetEntityContext(){
System.out.println("unsetEntityContext method");
ctx = null;
}
}

Create the Database Table


Because this example uses bean-managed persistence, you have to create the BONUS database
table in the CloudscapeDB database. With container-managed persistence, the table is cre-
ated for you.
To make things easy, the database table is created with two scripts: createTable.sql and
cloudTable.sh (Unix) or cloudTable.bat (Windows/NT). For this example, the cre-
ateTable.sql script goes in your ~/J2EE/Beans directory, and the cloudTable.sh (Unix)
or cloudTable.bat (Windows/NT) script goes in your ~/J2EE directory.

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


102 APRIL 18, 2000

createTable.sql
This file is provided in the code download for this lesson.
drop table bonus;

create table bonus


(socsec varchar(9) constraint pk_bonus primary key,
bonus decimal(10,2));

exit;

cloudTable.bat
This file is provided in the code download for this lesson.
rem cloudTable.bat
rem Creates BONUS table in CloudscapeDB.
rem
rem Place this script in ~\J2EE
rem To run: cd ~\J2EE\cloudTable.sh
rem
rem Change this next line to point to *your*
rem j2sdkee1.2 installation
rem
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
rem
rem Everything below goes on one line
java -Dij.connection.CloudscapeDB=
jdbc:rmi://localhost:1099/jdbc:cloudscape:
CloudscapeDB\;create=true -Dcloudscape.system.home=
%J2EE_HOME%\cloudscape -classpath
%J2EE_HOME%ıib\cloudscape\client.jar;
%J2EE_HOME%ıib\cloudscape\ tools.jar;
%J2EE_HOME%ıib\cloudscape\cloudscape.jar;
%J2EE_HOME%ıib\cloudscape\RmiJdbc.jar;
%J2EE_HOME%ıib\cloudscapeıicense.jar;
%CLASSPATH% -ms16m -mx32m
COM.cloudscape.tools.ij createTable.sql

cloudTable.sh
This file is provided in the code download for this lesson.
#!/bin/sh
#
# cloudTable.sh
# Creates BONUS table in CloudscapeDB.
#
# Place this script in ~\J2EE
# To run: cd ~\J2EE\cloudTable.sh
#

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 103

# Change this next line to point to *your*


# j2sdkee1.2 installation
#
J2EE_HOME=/home/monicap/J2EE/j2sdkee1.2
#
# Everything below goes on one line
java -Dij.connection.CloudscapeDB=jdbc:rmi:
//localhost:1099/jdbc:cloudscape:CloudscapeDB\;
create=true -Dcloudscape.system.home=
$J2EE_HOME/cloudscape -classpath
$J2EE_HOME/lib/cloudscape/client.jar:
$J2EE_HOME/lib/cloudscape/tools.jar:
$J2EE_HOME/lib/cloudscape/cloudscape.jar:
$J2EE_HOME/lib/cloudscape/RmiJdbc.jar:
$J2EE_HOME/lib/cloudscape/license.jar:
${CLASSPATH} -ms16m -mx32m
COM.cloudscape.tools.ij createTable.sql

Uninstall J2EE Application


Before you can redeploy the J2EE application with the changes for this lesson, you have to
uninstall the Lesson 2 J2EE application. You can do this any time before you deploy, but just
to make sure you do not forget, do it now.
At the bottom of the Deploy tool is a window listing BonusApp with an Uninstall button to
the right. Click Uninstall.

Delete and Create EJB JAR File


In this lesson, you will delete the JAR file with the session and entity Beans, and then create
a new JAR file using the container-managed session Bean from previous lessons and the
bean-managed persistence entity Bean from this lesson.

Delete JAR File


Click the BonusApp application in the Local Applications window so you can see its
application components. Select 2BeansJar so it is outlined highlighted.
At the top of the Deploy tool, there is an Edit menu. Select Delete.

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


104 APRIL 18, 2000

Create JAR with Session Bean


With BonusApp selected,
• Select File.New Enterprise Bean from the menus at the top.
• Introduction: Read and click Next.
• EJB JAR: Make sure BonusApp shows in the Enterprise Bean will go in field. Spec-
ify 2BeansJar as the display name. Click Add (the one next to the Contents window).
Toggle the directory so the Beans directory displays with its contents.
• Select Calc.class, Click Add.
• Select CalcBean.class. Click Add.
• Select CalcHome.class. Click Add.
• Enterprise Bean JAR classes: Make sure you see Beans/Calc.class, Beans/Cal-
cHome.class, and Beans/CalcBean.class in the display.
• Click OK.
• EJB JAR: Click Next.
• General: Make sure Beans.CalcBean is the classname, Beans.CalcHome is the Home
interface, and Beans.Calc is the Remote interface. Enter CalcBean as the display
name. Click session and stateless. Click Next.
• Environment Entries: Click Next. This simple session Bean does not use properties
(environment entries).
• Enterprise Bean References: Click Next. The references are handled during deploy-
ment rather than here.
• Resource References: Click Next. This simple session Bean does not look up a data-
base or JavaMail session object.
• Security: Click Next. This simple session Bean does not use security roles.
• Transaction Management: Select Container-managed transactions (if it is not
already selected). In the list below make calcBonus, and getRecord required. This
means the container starts a new transaction before running these methods. The trans-
action commits just before the methods end. You can find more information on these
transaction settings in Chapter 6 of the Enterprise JavaBeans Developer's Guide. Click
Next.
• Review Settings: Click Finish.
• In the Local Applications window, select BonusApp. In the Inspecting window,
select JNDI names, give CalcBean the JNDI name of calcs, and press the Return key.

Add the Entity Bean


WIth 2BonusApp selected,
• Select File.New Enterprise Bean from the menus at the top.
• Introduction: Read and click Next.

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 105

• EJB JAR: Make sure 2BeansJar shows in the Enterprise Bean will go in field. This
setting will add the new Bean to the existing JAR file instead of putting the new Bean
in its own JAR file. Specify 2BeansJar as the display name. Click Add (the one next to
the Contents window). Toggle the directory so the Beans directory displays with its
contents.
• Select Bonus.class, Click Add.
• Select BonusBean.class. Click Add.
• Select BonusHome.class. Click Add.
• Enterprise Bean JAR classes: Make sure you see Beans/Bonus.class, Beans/
BonusHome.class, and Beans/BonusBean.class in the display.
• Click OK.
• EJB JAR: Click Next.
• General: Make sure Beans.BonusBean is the classname, Beans.BonusHome is the
Home interface, and Beans.Bonus is the Remote interface. Enter BonusBean as the dis-
play name. Click Entity. Click Next.
• Entity Settings: Select Bean managed persistence. Make the primary key class
java.lang.String. Click Next.
• Environment Entries: Click Next. This simple entity Bean does not use properties
(environment entries).
• Enterprise Bean References: Click Next. This simple entity Bean does not reference
other enterprise Beans.
• Resource References: Click Add. In the Coded name column, type jdbc/BonusDB.
This is the database name you specified in BonusBean for the dbName instance variable.
Click Next.
• Security: Click Next. This simple entity Bean does not use security roles.
• Transaction Management: Select Container-managed transactions (if it is not
already selected). In the list below make create, findByPrimaryKey, getBonus and
getSocSec required. This means the container starts a new transaction before running
these methods. The transaction commits just before the methods end. You can find
more information on these transaction settings in Chapter 6 of the Enterprise Java-
Beans Developer's Guide. Click Next.
• Review Settings: Click Finish.
• In the Local Applications window, select BonusApp. In the Inspecting window,
select JNDI names, give BonusBean the JNDI name of bonus, CalcBean the JNDI
name of calcs, jdbc/BonusDB the JNDI name of jdbc/Cloudscape, and press the
Return key.

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


106 APRIL 18, 2000

Verify and Deploy the J2EE Application


Before you deploy the application, it is a good idea to run the verifier. The verifier will pick
up errors in the application components such as missing enterprise Bean methods that the
compiler does not catch.

Verify
With BonusApp selected, choose Verifier from the Tools menu. In the dialog that pops up,
click OK. The window should tell you that all tests passed. That is, if you used the session
Bean code provided for this lesson. Close the verifier window because you are now ready to
deploy the application.

Note: In the Version 1.2 software you might get a tests app.WebURI error. This
means the deploy tool did not put a .war extension on the WAR file during WAR file cre-
ation. This is a minor bug and the J2EE application deploys just fine in spite of it. Also,
you also might see some warnings telling you that java.rmi.RemoteException is
deprecated. You can ignore this for now.

Deploy
From the Tools menu, choose Deploy Application. A Deploy BonusApp dialog box pops
up. Verify that the Target Server selection is either localhost or the name of the host running
the J2EE server.
Make sure the Return Client Jar box is checked.
Click Next.
Make sure the JNDI names show for calcs for CalcBean, bonus for BonusBean, and jdbc/
Cloudscape for jdbc/BonusDB. If they do not, type the JNDI names in yourself, and press
the Return key.
Click Next.
Make sure the Context Root name shows JSPRoot. If it does not, type it in yourself and press
the Return key.
Click Next.
Click Finish to start the deployment. A dialog box pops up that displays the status of the
deployment operation. When it is complete, the three bars on the left will be completely
shaded. When that happens, click OK.

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 107

Run the J2EE Application


The web server runs on port 8000 by default. To open the bonus.jsp page point your
browser to http://localhost:8000/JSPRoot/bonus.jsp, which is where the Deploy tool
put the JSP page.
Fill in a social security number and multiplier, and click the Submit button. BonusServlet
processes your data, returns an HTML page with the bonus calculation on it, and prints the
simple XML report.
The J2EE server output might show the following message each time database access is
attempted. The message means no user name and password were supplied to access the data-
base. You can ignore this message because a user name and password are not required to
access the Cloudscape database, and this example works just fine regardless of the message.
Cannot find principal mapping information for data source with JNDI name
jdbc/Cloudscape

Here is a cleaned up version of the J2EE server output (the above message was edited out).
setEntityContext method
Create Method
Post Create

setEntityContext method
Find by primary key
Load method

getBonus
Store method
Load method

getSocSec
Store method
Find by primary key
Load method

getSocSec
Store method
Load method

getBonus
Store method

<?xml version="1.0"?>
<report>
<bonusCalc ssnum="777777777" bonusAmt="300.0" />
</report>

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


108 APRIL 18, 2000

More Information
You can get more information on entity Beans and bean-managed persistence here:
http://java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/Entity.fm.html

You can get more information on making database connections here:


http://java.sun.com/j2ee/j2sdkee/techdocs/guides/ejb/html/Database.fm.html

LESSON 7 JDBC TECHNOLOGY AND BEAN-MANAGED PERSISTENCE


APRIL 18, 2000 109

Index
A doGet method 7
application assembly 16
E
application components editing information 22
editing information 22 ejbCreate method 12, 28
working together 10 EJBObject class 12
application deployment 24, 54, 65, 82, 106 Enterprise Archive (EAR) file 16
application verification 23, 54, 64, 81, 106 entity Bean
avax.rmi.RemoteException 12 container managed 29
B defined 27
bonus.html file 6
F
BonusServlet code 6 findByPrimaryKey method 28
C G
Cloudscape database 27 getBonus method 28
container managed getSocSec method 28
persistence 29 H
transaction management 29
home interface
Content pane 22
looking up 7
context root
role of 11
calling a servlet in an HTML form 6
HTTP headers 7
specify 22
HttpServlet class 7
create method 12, 28
CreateException class 11 I
D IOException class 7
deploy application 24, 54, 65, 82, 106 J
deploy tool J2EE application components
assemble application 16 defined 4
deploy application 24, 54, 65, 82, 106 j2ee -verbose command 14
described 15 Java Archive (JAR) 16
editing information 22 java.io 7
verify application 23, 54, 64, 81, 106 javax.naming 7
view application components 19 javax.rmi 7
deploytool command 14 javax.servlet 7

INDEX
APRIL 18, 2000 110

javax.servlet.http 7 T
JNDI name
thin-client application defined 2
how used 7
transaction management 29
specify 22
transaction rollback 27
L
U
looking up the home interface 7
Uninstall button 15
M
V
meta information 16
verify application 23, 54, 64, 81, 106
method signatures 28
Multitier architecture W
defined 2 Web Archive (WAR) file 16, 19
multitier architecture
example 3
P
persistent data 27
PortableRemoteObject class 7
primary key 28
duplicate 28
R
remote interface 12
request object 7
response object 7
run application 25, 56, 66, 83, 107
S
ServletException class 7
session Bean
defined 10
SessionBean interface 12
setSessionContext method 12
signatures, methods 28

INDEX

You might also like