J2EE
J2EE
by Monica Pawlan
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.
iii
Preface
This tutorial introduces you to the APIs, tools, and services provided in the Java 2 Enter-
prise Edition (J2EE) Reference Implementation. You can get the J2EE Reference Implemen-
taion as a free download (http://developer.java.sun.com/developer/earlyAccess/
j2sdkee/) for demonstrations, prototyping, educational use, and verifying J2EE application
portability.
To support these uses the J2EE Reference Implementation comes with J2EE development
and deployment tools, Java WebServer 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]
Online Copies
You can find an online version of this material at the JDC:
Writing Enterprise Applications for the J2EE Reference Implementation:
http://developer.java.sun.com/developer/onlineTraining/J2EE/Intro/
index.html
iv
v
Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Online Copies iii
A Simple Session Bean. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
Example Thin-Client Multitiered Application 2
J2EE Software and Setup 3
Unix: 3
Windows: 3
Path Settings 3
Unix: 3
Windows: 4
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 7
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: 15
Windows: 15
Deploy Tool 15
vi
L E S S O N 1
This lesson introduces you to J2EE applications programming, and the J2EE Reference
Implementation by showing you how to write a simple thin-client multitiered enterprise
application.
The J2EE Reference Implementation is a non-commercial operational definition of the J2EE
platform and specification made freely available by Sun Microsystems for demonstrations,
prototyping, and educational 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
• J2EE Software and Setup
• Path Settings
• Classpath Settings
• J2EE Application Components
• Create the HTML File
• Create the Servlet
• Servlet Code
• Create the Session Bean and Servlet
• Start the J2EE Application Server
• Start the Deploy Tool
• Assemble the J2EE Application
• Verify and Deploy the J2EE Application
• Run the J2EE Application
2
Browser
Network
Thin-Client
Tier Servlet
1
Network
Network
Tier Database
3 Server
3
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).
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, HTTP, HTTP over
secure socket layer (SSL) also known as HTTPS, development and deployment tools, and
the Java APIs for the Enterprise. To use these features, set your path and class path variables
as described here.
Path Settings
Path settings make the development and deployment tools accessible from anywhere on your
system.
Unix:
/home/monicap/J2EE/jdk1.2.2/bin
/home/monicap/J2EE/j2sdkee1.2/bin
4
Windows:
\home\monicap\J2EE\jdk1.2.2\bin
\home\monicap\J2EE\j2sdkee1.2\bin
Unix:
/home/monicap/J2EE/j2sdkee1.2/lib/j2ee.jar
Windows:
\home\monicap\J2EE\j2sdkee1.2\lib\j2ee.jar
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.
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 Code
The example assumes this file 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>
Import Statements
The servlet code begins with import statements for these packages:
• 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 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.
8
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();
}
9
Servlet Code
Here is the full code. The example assumes this file is in the ClientCode directory on Unix.
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import Beans.*;
Home
Interface
Session
Browser Servlet Bean
Remote
Interface
The next sections show the session Bean code. The example assumes these files are placed in
the /home/monicap/J2EE/Beans directory 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;
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;
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;
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
Windows
cd \home\monicap\J2EE\ClientCode
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar:
\home\monicap\J2EE:
\home\monicap\J2EE\Beans
javac -d . -classpath %CPATH% BonusServlet.java
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.
If that does not work, do the following from the J2EE directory:
15
Unix:
j2sdkee1.2/bin/deploytool
Windows:
j2sdkee1.2\bin\deploytool
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.
16
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.
Here is a summary of the assembly steps, which are discussed in more detail below.
17
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.
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.
18
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.
19
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.CalcHome
20
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.
21
Select BonusServlet.class. Make sure the WAR contents shows the listing as
bonus.html without the ClientCode directory prefixed to the name.
Click Add.
Click Next.
Choose the ClientCode directory again.
22
Select bonus.html. Be sure the WAR contents shows the listing as bonus.html without
the ClientCode directory prefixed to the name.
Click Add.
Click Finish.
The Add Contents to WAR dialog box should look like the one in Figure 8.
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.
JNDI Name
To specify the JNDI name, select BonusApp in the Local Applications window. The Inspect-
ing window displays tabs at the top, and one of those tabs is JNDI Names. Select it.
24
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.
j2sdkee1.2
public_html
BonusRoot
WEB-INF bonus.html
classes
BonusServlet.class
Verify
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. 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 selectionis either localhost or the name of the jost 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 book should not be checked. Checking this box creates a JAR file withg
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
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. 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 tFigure 10. When that happens, click OK.
26
L E S S O N 2
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 Reference Implementation 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 data-
base access operations. The table is created and the SQL code generated with the Deploy
tool during assembly and deployment.
• Create the Entity Bean
• Change the Servlet
• Compile
• Start the Platform and Tools
• Assemble and Deploy
• Run the J2EE Application
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;
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;
Component Component
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.
30
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
return this.bonus;
}
public String getSocSec() {
return this.socsec;
}
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
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: " +
34
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.
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
Windows:
cd \home\monicap\J2EE\ClientCode
set J2EE_HOME=\home\monicap\J2EE\j2sdkee1.2
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar:
\home\monicap\J2EE:
\home\monicap\J2EE\Beans
javac -d . -classpath %CPATH% BonusServlet.java
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
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.
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.
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).
• 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.
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.
42
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.
43
3
L E S S O N 4
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
• Change the Servlet
• Compile
• Start the Platform and Tools
• Assemble and Deploy
• Run the J2EE Application
44
Browser Servlet
Session Bean
bonus.html BonusServlet.class
calcBonus method
getRecord method
Entity Bean
Database
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;
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;
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;
46
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.ejb.RemoveException;
import javax.ejb.DuplicateKeyException;
import javax.ejb.CreateException;
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.
48
As before in A Simple Entity Bean (page 27), the catch statement catches and handles
duplicate primary key values (social security numbers).
try {
//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.
Windows
cd \home\monicap\J2EE
set J2EE_HOME=\home\monicap\J2EE\j2sdkee-beta
set CPATH=.;%J2EE_HOME%\lib\j2ee.jar
javac -d . -classpath %CPATH% Beans/BonusBean.java
Beans/BonusHome.java Beans/Bonus.java
Windows:
cd \home\monicap\J2EE\ClientCode
set J2EE_HOME=\home\monicap\J2EE\j2sdkee-beta set
CPATH=.;%J2EE_HOME%\lib\j2ee.jar:\home\monicap\J2EE:
\home\monicap\J2EE/Beans
javac -d . -classpath %CPATH% BonusServlet.java
If that does not work, type this from the J2EE directory:
Unix
j2sdkee-beta/bin/j2ee -verbose
j2sdkee-beta/bin/deploytool
j2sdkee-beta/bin/cloudscape -start
50
Windows
j2sdkee-beta\bin\j2ee -verbose
j2sdkee-beta\bin\deploytool
j2sdkee-beta\bin\cloudscape -start
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”
54
FROM “BonusBeanTable” WHERE “socsec”=?. The question mark (?) represents the
parameter passed to the findByPrimaryKey method.
• Click OK.
Verify
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. 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 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.
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.
55
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 tFigure 15. When that happens, click OK.
If you supply the same social security number twice, you will see something similar to this:
Bonus Calculation
Index
A doGet method 7
application assembly 16
E
application components editing information 23
editing information 23 ejbCreate method 12, 28
working together 10 EJBObject class 12
application deployment 25, 54 Enterprise Archive (EAR) file 16
application verification 24, 54 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 23
looking up 7
context root
role of 11
calling a servlet in an HTML form 6
HTTP headers 7
specify 23
HttpServlet class 7
create method 12, 28
CreateException class 11 I
D IOException class 7
deploy application 25, 54 J
deploy tool J2EE application components
assemble application 16 defined 4
deploy application 25, 54 j2ee -verbose command 14
described 15 Java Archive (JAR) 16
editing information 23 java.io 7
verify application 24, 54 javax.naming 7
view application components 20 javax.rmi 7
deploytool command 14 javax.servlet 7
58
javax.servlet.http 7 T
JNDI name
thin-client application defined 2
how used 7
transaction management 29
specify 23
transaction rollback 27
L
U
looking up the home interface 7
Uninstall button 16
M
V
meta information 17
verify application 24, 54
method signatures 28
Multitier architecture W
defined 2 Web Archive (WAR) file 16, 20
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 26, 55
S
ServletException class 7
session Bean
defined 10
SessionBean interface 12
setSessionContext method 12
signatures, methods 28