The CartBean Example
The
CartBean
session bean represents a shopping cart in an online bookstore. The bean's client can add a book to the cart, remove a book, or retrieve the cart's contents. To constructCartBean
, you need the following code:
- Session bean class (
CartBean
)- Home interface (
CartHome
)- Remote interface (
Cart
)All session beans require a session bean class. All enterprise beans that permit remote access must have a home and a remote interface. To meet the needs of a specific application, an enterprise bean may also need some helper classes. The
CartBean
session bean uses two helper classes (BookException
andIdVerifier
) which are discussed in the section Helper Classes.The source code for this example is in the
<
INSTALL
>/j2eetutorial14/examples/ejb/cart/
directory.Session Bean Class
The session bean class for this example is called
CartBean
. Like any session bean, theCartBean
class must meet these requirements:
- It implements the
SessionBean
interface.- The class is defined as
public
.- The class cannot be defined as
abstract
orfinal
.- It implements one or more
ejbCreate
methods.- It implements the business methods.
- It contains a
public
constructor with no parameters.- It must not define the
finalize
method.The source code for the
CartBean
class follows.import java.util.*; import javax.ejb.*; public class CartBean implements SessionBean { String customerName; String customerId; Vector contents; public void ejbCreate(String person) throws CreateException { if (person == null) { throw new CreateException("Null person not allowed."); } else { customerName = person; } customerId = "0"; contents = new Vector(); } public void ejbCreate(String person, String id) throws CreateException { if (person == null) { throw new CreateException("Null person not allowed."); } else { customerName = person; } IdVerifier idChecker = new IdVerifier(); if (idChecker.validate(id)) { customerId = id; } else { throw new CreateException("Invalid id: "+ id); } contents = new Vector(); } public void addBook(String title) { contents.addElement(title); } public void removeBook(String title) throws BookException { boolean result = contents.removeElement(title); if (result == false) { throw new BookException(title + "not in cart."); } } public Vector getContents() { return contents; } public CartBean() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext sc) {} }The SessionBean Interface
The
SessionBean
interface extends theEnterpriseBean
interface, which in turn extends theSerializable
interface. TheSessionBean
interface declares theejbRemove
,ejbActivate
,ejbPassivate
, andsetSessionContext
methods. TheCartBean
class doesn't use these methods, but it must implement them because they're declared in theSessionBean
interface. Consequently, these methods are empty in theCartBean
class. Later sections explain when you might use these methods.The ejbCreate Methods
Because an enterprise bean runs inside an EJB container, a client cannot directly instantiate the bean. Only the EJB container can instantiate an enterprise bean. During instantiation, the example program performs the following steps.
- The client invokes a
create
method on the home object:
Cart shoppingCart = home.create("Duke DeEarl","123");
- The EJB container instantiates the enterprise bean.
- The EJB container invokes the appropriate
ejbCreate
method inCartBean
:
public void ejbCreate(String person, String id)
throws CreateException {
if (person == null) {
throw new CreateException("Null person not allowed.");
}
else {
customerName = person;
}
IdVerifier idChecker = new IdVerifier();
if (idChecker.validate(id)) {
customerId = id;
}
else {
throw new CreateException("Invalid id: "+ id);
}
contents = new Vector();
}Typically, an
ejbCreate
method initializes the state of the enterprise bean. The precedingejbCreate
method, for example, initializes thecustomerName
andcustomerId
variables by using the arguments passed by thecreate
method.An enterprise bean must have one or more
ejbCreate
methods. The signatures of the methods must meet the following requirements:
- The access control modifier must be
public
.- The return type must be
void
.- If the bean allows remote access, the arguments must be legal types for the Java Remote Method Invocation (Java RMI) API.
- The modifier cannot be
static
orfinal
.The
throws
clause can include thejavax.ejb.CreateException
and other exceptions that are specific to your application. TheejbCreate
method usually throws aCreateException
if an input parameter is invalid.Business Methods
The primary purpose of a session bean is to run business tasks for the client. The client invokes business methods on the remote object reference that is returned by the
create
method. From the client's perspective, the business methods appear to run locally, but they actually run remotely in the session bean. The following code snippet shows how theCartClient
program invokes the business methods:Cart shoppingCart = home.create("Duke DeEarl", "123"); ... shoppingCart.addBook("The Martian Chronicles"); shoppingCart.removeBook("Alice In Wonderland"); bookList = shoppingCart.getContents();The
CartBean
class implements the business methods in the following code:public void addBook(String title) { contents.addElement(title); } public void removeBook(String title) throws BookException { boolean result = contents.removeElement(title); if (result == false) { throw new BookException(title + "not in cart."); } } public Vector getContents() { return contents; }The signature of a business method must conform to these rules:
- The method name must not conflict with one defined by the EJB architecture. For example, you cannot call a business method
ejbCreate
orejbActivate
.- The access control modifier must be
public
.- If the bean allows remote access, the arguments and return types must be legal types for the Java RMI API.
- The modifier must not be
static
orfinal
.The
throws
clause can include exceptions that you define for your application. TheremoveBook
method, for example, throws theBookException
if the book is not in the cart.To indicate a system-level problem, such as the inability to connect to a database, a business method should throw the
javax.ejb.EJBException
. When a business method throws anEJBException
, the container wraps it in aRemoteException
, which is caught by the client. The container will not wrap application exceptions such asBookException
. BecauseEJBException
is a subclass ofRuntimeException
, you do not need to include it in thethrows
clause of the business method.Home Interface
A home interface extends the
javax.ejb.EJBHome
interface. For a session bean, the purpose of the home interface is to define thecreate
methods that a remote client can invoke. TheCartClient
program, for example, invokes thiscreate
method:Cart shoppingCart = home.create("Duke DeEarl", "123");Every
create
method in the home interface corresponds to anejbCreate
method in the bean class. The signatures of theejbCreate
methods in theCartBean
class follow:public void ejbCreate(String person) throws CreateException ... public void ejbCreate(String person, String id) throws CreateExceptionCompare the
ejbCreate
signatures with those of thecreate
methods in theCartHome
interface:import java.io.Serializable; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface CartHome extends EJBHome { Cart create(String person) throws RemoteException, CreateException; Cart create(String person, String id) throws RemoteException, CreateException; }The signatures of the
ejbCreate
andcreate
methods are similar, but they differ in important ways. The rules for defining the signatures of thecreate
methods of a home interface follow.
- The number and types of arguments in a
create
method must match those of its correspondingejbCreate
method.- The arguments and return type of the
create
method must be valid RMI types.- A
create
method returns the remote interface type of the enterprise bean. (But anejbCreate
method returnsvoid
.)- The
throws
clause of thecreate
method must include the java.rmi.RemoteException
and thejavax.ejb.CreateException
.Remote Interface
The remote interface, which extends
javax.ejb.EJBObject
, defines the business methods that a remote client can invoke. Here is the source code for theCart
remote interface:import java.util.*; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Cart extends EJBObject { public void addBook(String title) throws RemoteException; public void removeBook(String title) throws BookException, RemoteException; public Vector getContents() throws RemoteException; }The method definitions in a remote interface must follow these rules:
- Each method in the remote interface must match a method implemented in the enterprise bean class.
- The signatures of the methods in the remote interface must be identical to the signatures of the corresponding methods in the enterprise bean class.
- The arguments and return values must be valid RMI types.
- The
throws
clause must include thejava.rmi.RemoteException
.Helper Classes
The
CartBean
session bean has two helper classes:BookException
andIdVerifier
. TheBookException
is thrown by theremoveBook
method, and theIdVerifier
validates thecustomerId
in one of theejbCreate
methods. Helper classes must reside in the EJB JAR file that contains the enterprise bean class.Building the CartBean Example
Now you are ready to compile the remote interface (
Cart.java
), the home interface (CartHome.java
), the enterprise bean class (CartBean.java
), the client class (CartClient.java
), and the helper classes (BookException.java
andIdVerifier.java
).
- In a terminal window, go to this directory:
<
INSTALL
>/j2eetutorial14/examples/ejb/cart/
- Type the following command:
asant build
Creating the Application
In this section, you'll create a J2EE application named
CartApp
, storing it in the fileCartApp.ear
.
- In
deploytool
, select FileRight ArrowNewRight ArrowApplication.- Click Browse.
- In the file chooser, navigate to
<INSTALL>
/j2eetutorial14/examples/ejb/cart/
.- In the File Name field, enter
CartApp
.- Click New Application.
- Click OK.
- Verify that the
CartApp.ear
file resides in<
INSTALL
>/j2eetutorial14/examples/ejb/cart/
.Packaging the Enterprise Bean
- In
deploytool
, select FileRight ArrowNewRight ArrowEnterprise Bean.- In the EJB JAR screen:
- Select Create New JAR Module in Application.
- In the Create New JAR Module in Application field, select
CartApp
.- In the JAR Name field, enter
CartJAR
.- Click Choose Module File.
- Click Edit Contents.
- Locate the
<
INSTALL
>/j2eetutorial14/examples/ejb/cart/build/
directory.- Select
BookException.class
,Cart.class
,CartBean.class
,CartHome.class
, andIdVerifier.class
.- Click Add.
- Click OK.
- Click Next.
- In the General screen:
- In the Enterprise Bean Class field, select
CartBean
.- In the Enterprise Bean Name field, enter
CartBean
.- In the Enterprise Bean Type field, select
Stateful Session
.- In the Remote Home Interface field, select
CartHome
.- In the Remote Interface field, select
Cart
.- Click Next.
- Click Finish.
Packaging the Application Client
To package an application client component, you run the New Application Client wizard of
deploytool
. During this process the wizard performs the following tasks.
- Creates the application client's deployment descriptor
- Puts the deployment descriptor and client files into a JAR file
- Adds the JAR file to the application's
CartApp.ear
fileTo start the New Application Client wizard, select FileRight ArrowNewRight ArrowApplication Client. The wizard displays the following dialog boxes.
- Introduction dialog box
- Read the explanatory text for an overview of the wizard's features.
- Click Next.
- JAR File Contents dialog box
- Select the button labeled Create New AppClient Module in Application.
- In the combo box below this button, select
CartApp
.- In the AppClient Display Name field, enter
CartClient
.- Click Edit Contents.
- In the tree under Available Files, locate the
<INSTALL>
/j2eetutorial14/examples/ejb/cart/build
directory.- Select
CartClient.class
.- Click Add.
- Click OK.
- Click Next.
- General dialog box
- In the Main Class combo box, select
CartClient
.- Click Next.
- Click Finish.
Specifying the Application Client's Enterprise Bean Reference
When it invokes the
lookup
method, theCartClient
refers to the home of an enterprise bean:Object objref = initial.lookup("java:comp/env/ejb/SimpleCart
");You specify this reference as follows.
- In the tree, select
CartClient
.- Select the EJB Ref's tab.
- Click Add.
- In the Coded Name field, enter
ejb/SimpleCart
.- In the EJB Type field, select Session.
- In the Interfaces field, select Remote.
- In the Home Interface field, enter
CartHome
.- In the Local/Remote Interface field, enter
Cart
.- In the JNDI Name field, select
CartBean
.- Click OK.
Deploying the Enterprise Application
Now that the J2EE application contains the components, it is ready for deployment.
- Select
CartApp
.- Select ToolsRight ArrowDeploy.
- Under Connection Settings, enter the user name and password for the Application Server.
- Under Application Client Stub Directory, check Return Client Jar.
- In the field below the checkbox enter
<INSTALL>
/j2eetutorial14/examples/ejb/cart/
.- Click OK.
- In the Distribute Module dialog box, click Close when the deployment completes.
- Verify the deployment.
- In the tree, expand the Servers node and select the host that is running the Application Server.
- In the Deployed Objects table, make sure that
CartApp
is listed and that its status isRunning
.- Verify that
CartAppClient.jar
is in<INSTALL>
/j2eetutorial14/examples/ejb/cart/.
Running the Application Client
To run the application client, perform the following steps.
- In a terminal window, go to the
<INSTALL>
/j2eetutorial14/
directory.
examples/ejb/cart/- Type the following command:
appclient -client CartAppClient.jar
- In the terminal window, the client displays these lines:
The Martian Chronicles
2001 A Space Odyssey
The Left Hand of Darkness
Caught a BookException: Alice in Wonderland not in cart.