Download as pdf or txt
Download as pdf or txt
You are on page 1of 41

 

Working with JBOSS Application Server


SkillSoft. (c) 2003. Copying Prohibited.

  

Reprinted for Ashutosh Patel, Accenture


ashutosh.patel@accenture.com

All rights reserved. Reproduction and/or distribution in whole or in part in electronic,paper or


other forms without written permission is prohibited.
Working with JBOSS Application Server

Chapter 4: Creating and Deploying Enterprise Components


Enterprise components, also known as Enterprise Java Beans (EJB), are Java classes that are packaged and deployed on application
servers, such as JBoss, Weblogic, and Websphere. An EJB provides reusable business logic to applications that run in a multi-tiered
environment. These EJBs are instantiated by the application servers to provide the runtime environment for Web applications.

This chapter introduces EJBs and describes the types of EJBs, such as session and entity beans. The chapter also explains how to create
and deploy EJBs on the JBoss application server.

EJB Architecture
The EJB 2.0 specification provides a framework to develop and deploy EJBs. The EJB 2.0 specification also defines a bean-container
contract that defines a set of rules for the application server to manage EJBs. The application server uses these rules to manage the lifecycle
of an EJB and enables clients to invoke EJB methods. Application servers need to be compliant with the EJB 2.0 specification to run EJB-
based Web applications.

In Web applications, EJBs are abstracted to prevent direct end user interaction, using Java objects. These Java objects implement the
java.rmi.Remote interface to be identifiable over a network. As a result, such Java objects are also called remote objects. These remote
objects are instantiated and managed by the application server to serve client requests.

The EJB architecture consists of an EJB server, EJB container, home object, remote object, and clients. The functions of these components
are:

n EJB container: Provides the runtime environment and resources to execute enterprise applications. The EJB container also provides Java
objects, such as EJBOBject and EJBHome instances required to execute an application. The EJB container also enables an enterprise
application to use services, such as transaction and security management, which are provided by the application server.

n Home object: Manages the lifecycle of an EJB, The home object are network-accessible objects that implements a user-defined home
interface, which contains the code to create, retrieve, or remove a specific EJB instance.

n Remote object: Enable clients to invoke the methods in an EJB. The remote objects are network-accessible objects that implement a
user-defined remote interface that contains business methods of the EJB. The business methods may use the available data in a
database to process client requests.

n Clients: Forwards the requests made by the end users to invoke EJB methods. These clients locate the EJB container using the Java
Naming and Directory Interface (JNDI). Client requests are processed using an instance of an EJBObject.

Figure 4-1 shows the EJB architecture:

Figure 4-1: The EJB Architecture

The javax.ejb Interfaces


The javax.ejb package, which is a part of J2EE, implements the EJB 2.0 specifications, and defines classes and interfaces to create EJBs.
The interfaces included in this package are:

n EJBHome

n EJBObject

n SessionBean
n EntityBean

The EJBHome Interface

Page 2 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

The EJBHome interface allows you to create a remote object, and manage the lifecycle of an EJB. The lifecycle of an EJB is affected when it
is created, accessed, or destroyed. A user-defined interface, called the home interface, extends the EJBHome interface, and defines methods
to create an EJB, or retrieve a specific instance of an EJB. Table 4-1 lists the methods of the EJBHome interface:
Table 4-1: Methods of the EJBHome Interface

Method Description Exception


getEJBMetaData Allows the EJB container to retrieve metadata of the EJB. This Throws an exception, called RemoteException, when a failure occurs in
() method is abstract, and returns an object of the EJBMetaData retuning the metadata.
interface.
remove Removes the EJB instance. The handle object passed as a Throws the RemoteException exception when the method fails to remove
(handle) parameter is an object implementing the javax.ejb.Handle an EJB instance. The method also throws the RemoveException exception
interface. The javax.ejb.Handle interface provides reference to when the EJB container or the EJB does not allow the client to remove the
an EJB instance. EJB instance.
remove Removes an EJB instance identified by its primary key. This Throws the RemoteException, RemoveException when the method fails to
(object) method is abstract and returns void. remove the EJB instance.

Note Metadata refers to hidden information about an EJB. The EJBMetaData object encapsulates information about the home interface,
primary key, remote interface, and the type of EJB.

The EJBObject Interface


The EJBObject interface provides methods to store the state of an EJB instance, and to access information in a database, using the services
of the EJB container. A user-defined interface, called the remote interface, extends the EJBObject interface, and defines the business
methods of an EJB. Business methods implement the business logic of the application.

Table 4-2 lists the methods of the EJBObject interface:


Table 4-2: Methods of the EJBObject Interface

Method Description Exception


getEJBHome() Obtains a reference to an EJBHome object. This method is Throws the RemoteException exception, when the method fails to
abstract, and returns an object of the EJBHome interface. obtain a reference to an object.
getHandle() Obtains the handle for an EJB. The EJB client makes use of the Throws the RemoteException exception, when the method fails to
handle to provide a reference to an EJB, and to modify an EJB. obtain a reference to a handle.
This is an abstract method that returns an object of the
javax.ejb.Handle interface.
getPrimaryKey() Obtains primary key of an EJB object. This method is abstract Throws the RemoteException exception, when the method fails to
and returns a java.lang.Object object. obtain a primary key instance.
isIdentical Tests if the EJBObject reference passed as a parameter to the Throws the RemoteException exception, when the method fails to
(EJBObject) method is identical to the EJB that invokes this method. This execute.
method is abstract, and returns a Boolean value.
remove() Removes an EJB. Throws the RemoteException exception, when a failure occurs in
removing an EJB. The method throws the RemoveException exception,
when the EJB container does not allow the client to access the
instance of the EJBObject.

The SessionBean Interface


The javax.ejb.SessionBean interface creates session beans that define methods to perform business tasks in an application. The
SessionBean interface extends the EnterpriseBean interface. For example, you can create a session bean that defines business methods to
calculate annual interest for a specified amount stored in a database.

The methods of a session bean are invoked when the client starts a session with the application server. The session information is client-
specific, and maintained by the EJB container that allows several sessions to run simultaneously.
Session beans implement the javax.ejb.SessionBean interface. Table 4-3 lists the methods of the SessionBean interface:
Table 4-3: Methods of the SessionBean Interface

Method Description Exception


ejbPassivate Passivates an EJB object. An object is said to be passivated if the resources associated with the object is EJBException and
() persisted by the EJB Container. This method returns void. RemoteException
ejbActivate() Activates an EJB object. An object is said to be activated when its resources persisted after passivation is EJBException and
restored back. This method returns void. RemoteException
ejbRemove() Removes an EJB from the EJB container. The lifecycle of the session bean ends with the ejbRemove() EJBExeption and
method. This method returns void. RemoteException

Page 3 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

The EntityBean Interface


The javax.ejb.EntityBean interface creates an entity bean to provide an object representation of persistent data in a database. The EntityBean
interface extends the EnterpriseBean interface. This bean contains attributes that map to the columns of a table in the database, and
manipulate information in these columns. You can retrieve an entity bean instance, using the value in the primary key column of a table. Table
4-4 lists the methods of the EntityBean interface:
Table 4-4: Methods of the EntityBean Interface

Method Description Exception

ejbPassivate() Removes an EJB instance and stores the state of an instance in the bean pool. The EJB container EJBException and
persists reusable bean instances in a bean pool. The EJB container invokes this method. This method RemoteException
does not take any parameters and returns void.
ejbActivate() Invoked when an EJB instance retrieved from a bean pool. The values of columns in a specific record EJBException and
in the database are retrieved and assigned to the attributes of an EJB instance. RemoteException
EjbLoad() Invoked when an EJB state needs to be refreshed. This method returns void. EJBException and
RemoteException
ejbRemove() Removes an EJB object. This method accepts no parameters and returns void. Throws the RemoveException
and EJBException
setEntityContext() Invoked when an EJB instance is created. This method associates the entity context with the EJB Throws the EJBException
instance. This method returns void. exception
unsetEntityContext Disassociates the runtime context from an EJB instance. This method is invoked when an EJB Throws EJBException and
() instance is passivated, and its state is stored in a bean pool. The method returns void. RemoteException
ejbStore Invoked when an EJB state needs to be changed. This method returns void. Throws EJBException and
RemoteException

Note The EntityContext interface encapsulates the runtime context for an entity bean. The EJB container provides the runtime context to
pass the environment-specific information needed to execute EJB methods.

Types of EJBs
You can categorize EJBs into two types based on the purpose they serve. The two types of EJBs are session bean and entity bean. You can
use a session bean to implement the business methods whereas you can use an entity bean to represents the business data.

Session Bean
A session bean encapsulates reusable business logic, performed by enterprise applications and can maintain the state of the client internally.
When the client completes a conversation, the session bean is destroyed, and the resources held by it are made available for other
applications. The client state maintained by the session bean is also destroyed in the process.
Session beans are of two types, stateful session bean and stateless session bean. If the EJB container maintains session-specific
information, such as the client identity, the session bean is said to be stateful. Session information is not maintained in case of stateless
session beans.

Lifecycle of a Session Bean

The lifecycle of a session consists of three stages. The first stage is the instantiation stage in which the EJB container instantiates and
associates the session bean with a particular session context. To instantiate a session bean, the EJB container invokes the ejbCreate() and
setSessionContext() methods. After associating the session bean with a context, the client can invoke the business methods of the session
bean.

The second stage of the session bean lifecycle is the passivation and deactivation of the session bean instance. In this stage, the EJB
container moves the unused session bean instances to a bean pool. The bean pool is a secondary storage area that contains the state of
unused session beans. This process is called passivation. It occurs when the EJB container invokes the ejbPassivate() method. When the
client requires a specific session bean instance, the container retrieves the session bean state from the bean pool. This process is called
activation, and occurs when the EJB container invokes the ejbActivate() method. An activated session bean is ready to receive method
invocations.

The third stage of the session bean lifecycle is destruction of the session bean instance. The bean instance is removed from the bean pool
when the EJB container invokes the ejbRemove() method.

A stateful session bean undergoes all the stages in the lifecycle of a session bean. In case of a stateless session bean, passivation stage
does not exist because a stateless session bean either exists or is destroyed.

Entity Beans
An entity bean represents data in persistent storage, such as database rows. For example, you can represent a customer or order in a
database table as an entity bean. The state of an entity bean is stored in the EJB container to ensure that entity bean instances exist beyond

Page 4 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

the lifetime of the application or the J2EE server process. This state maintenance process is similar to data persisted in the database. The
data exists even after the database server is shut down. An entity bean needs to persist information it encapsulates in the database.
Depending on the manner in which information is persisted, entity beans are classified as:
Lifecycle of an Entity Bean

The EJB container maintains the lifecycle of an entity bean. In the first stage of the lifecycle, the EJB container creates an instance of the entity
bean and associates the bean to an entity context using the ejbCreate() and setEntityContext()methods. The ejbCreate() method provides a
unique value, called the primary key, to retrieve a specific bean instance from the pool. The setEntityContext() method associates the bean
with context-specific information available in the EJB container.

In the second stage of the lifecycle, the entity bean instance is stored in a bean pool of ready instances. In this stage, the bean is not
associated with any specific EJBObject. When a new database record is created and accessed by the application, the EJB container
retrieves the bean instance from the bean pool. The container then invokes the ejbLoad() method and populates the bean with the column
values of the new database record. The client can obtain the database data by invoking the business methods of the entity bean.

When the client performs a transaction using the bean, the database record is updated, and the ejbStore() method is invoked.
After the client session ends, the ejbPassivate() method is invoked. This is the third stage of the entity bean lifecycle. In this stage, the
container passivates and sends the entity bean to the bean pool. The unsetEntityContext() method is invoked that disassociates the context
information associated with the bean. This method is invoked when the container removes a bean using the ejbRemove() method.
Container Managed Persistence Bean

In Container Managed Persistence (CMP) entity beans, the container manages the persistence of data. The data to be persisted is provided
as arguments to the create() method of the entity bean. The container calls the ejbCreate() callback method on the entity bean implementation
class, and passes the arguments of the create() method. The container saves the data to persisted to the database. After the ejbCreate()
method is invoked, the container calls the ejbPostCreate() method in the bean implementation class that can be used for initialization in the
future.

After initializing the entity bean, the client can invoke the business methods on the entity bean object. If the business methods are not invoked,
the container passivates the bean instance, and calls the ejbStore() method of the bean instance. This method updates the state of the bean in
the corresponding database. After updating the state, the container calls the ejbPassivate() method on the bean instance to disassociate the
resources used by the bean.

If the client invokes a business method on the passivated bean object, the container calls the ejbActivate() method to activate the bean
instance. While activating the bean, the container calls the ejbLoad() method to modify the state of the bean.

The container removes the unused bean instances by calling the remove() method on the bean object. This method deletes the bean instance
from the bean pool, which in turn, deletes the respective record in the database.

CMP entity beans enhance code reusability because they are not associated with any specific database. CMP entity beans can be deployed
on various third-party Java compliant application servers.

Bean Managed Persistence Bean

BMP entity bean is similar to a CMP Entity Bean except that the bean is responsible for persisting the data to the corresponding database. It
becomes the responsibility of the bean developer to code all the necessary SQL statements in the respective callback methods that will be
invoked by the container.
BMP entity beans contain the code to establish connection with the database, and perform database operations are embedded within the
methods of the BMP entity bean. Database operations defined in a BMP entity bean include retrieving or modifying database information.

JBoss Configuration Files


JBoss contains configuration files: standardjaws.xml, standardjbosscmp-jdbc.xml, and standardjboss.xml that provide information to the EJB
container to obtain resource information such as URL to the data source. These configuration files also provide information to map database
columns to Java data types.

The standardjaws.xml File


The standardjaws.xml file contains the code that configures database for JBoss. You can specify the default database connection to persist
entity beans in the standardjaws.xml configuration file. This file also contains information to map Java data type with the corresponding
SQLdata type. This file supports backward compatibility with EJB 1.1.

The standardjbosscmp-jdbc.xml File


This file contains commands to specify database settings for your application. This file is similar to the standardjaws.xml file, but this file is
used with EJB 2.0. This file is used to map entity attributes with database columns.

The standardjboss.xml File

Page 5 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

The standardjboss.xml file specifies the default container for each bean type. This file also specifies the components that have to be used by
the EJB container and persistence manager.

Creating a Stateful Session Bean


You will learn to create a PurchaseDebitCard application that uses a stateful session bean. This example describes a debit card transaction
wherein the client is provided a user interface to enter the amount the end user spent. A client session bean calculates the available balance
for the debit card. The business methods to debit the amount spent and retrieve the balance amount is defined in the remote interface called
PurchaseDebit. The reference to the remote interface is obtained from the home interface called PurchaseDebitHome. The business methods
in the remote interface are implemented in the EJB called PurchaseDebitEJB.

Creating the Home Interface


The home interface of the PurchaseDebitEJB bean defines a create() method that is invoked by the EJB container to create an EJBHome
instance. The EJBHome instance is the remote representation of the session bean. The PurchaseDebitHome class is the home interface for
the PurchaseDebitEJB bean. To create the PurchaseDebitHome class:
1. Import all the required Java packages.
2. Create a class called PurchaseDebitHome that extends the EJBHome interface.

Listing 4-1 shows the PurchaseDebitHome class:

Listing 4-1: The PurchaseDebitHome.java File

package purchaseDebit;
// Import necessary packages
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import java.rmi.RemoteException;
public interface PurchaseDebitHome extends EJBHome
{
// Declaring the create method for PurchaseDebitEJB bean
PurchaseDebit create(double amount) throws RemoteException, CreateException;
}

Creating the Remote Interface


The remote interface called PurchaseDebit extends the EJBObject interface, and defines the business methods of the session bean. These
business methods are implemented by the PurchaseDebitEJB session bean. The methods of the EJBObject interface are implemented by the
EJB container, which provides a remote object representing the PurchaseDebitEJB bean.

The PurchaseDebit class is the remote interface for the PurchaseDebitEJB session bean. To create the PurchaseDebit class:
1. Import the required Java packages.
2. Create a class called PurchaseDebit that extends the EJBObject interface.

Listing 4-2 shows the PurchaseDebit class:

Listing 4-2: The PurchaseDebit.java File

package purchaseDebit;
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface PurchaseDebit extends EJBObject
{
// Declaring the PurchaseDebitEJB beans business methods
public void debitValue(double amount) throws RemoteException;
public double getBalance() throws RemoteException;
}

Creating the Implementation Class


The session bean implements the abstract business methods of the remote interface and the SessionBean interface. The EJB container
invokes the methods of the SessionBean interface to access the EJB. Clients, and invoke the business methods of the PurchaseDebit remote

Page 6 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

interface. The PurchaseDebitEJB class is the bean class that implements the business methods of the application. To create the
PurchaseDebitEJB class:
1. Import the required Java packages.

2. Create a class, called PurchaseDebitEJB that extends the SessionBean interface.


Listing 4-3 shows the PurchaseDebitEJB class:

Listing 4-3: The PurchaseDebitEJB.java File

package purchaseDebit;
import javax.ejb.*;
public class PurchaseDebitEJB implements SessionBean
{
// Declare the variable to hold state information
double debitAmount;
/*
Standard ejb methods whose implementation is provided by the EJB Container
*/
public void ejbActivate()
{
}
public void ejbPassivate()
{
}
public void ejbRemove()
{
}
public void setSessionContext(SessionContext ctx)
{
}
// This method creates the stateful session bean and initializes the bean with a value
public void ejbCreate(double amount)
throws CreateException
{
if(amount < 0)
{
throw new CreateException("Invalid amount");
}
debitAmount = amount;
}
// Implementations for the beans business methods
public void debitValue(double amount)
{
if(debitAmount < amount)
System.out.println("Insufficient Balance ... Transaction terminated");
else
debitAmount -= amount;
}
// This method returns the current state value stored in the variable
public double getBalance()
{
return debitAmount;
}
}

Creating the Client Class


The client invokes the session bean methods using the services provided by the JBoss server. These services include obtaining references to
the EJBHome and EJBObject interfaces. The client for the PurchaseDebitEJB bean is a console application called PurchaseDebitClient that
is the client class for the PurchaseDebitEJB bean. To create the PurchaseDebitClient class:
1. Import required Java packages, such as the javax.ejb, javax.swing,java.awt, and javax.naming.

2. Create a class which extends a javax.swing.JFrame and implements the ActionListener interface, as in Listing 4-4:

Listing 4-4: Creating the Class

Page 7 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

// Import necessary packages


import purchaseDebit.PurchaseDebitHome;
import purchaseDebit.PurchaseDebit;
import java.awt.*;
import java.awt.event.*;
import java.rmi.*;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;
import javax.swing.*;
import javax.ejb.CreateException;
// Create a client class that provides Swing component based UI
public class PurchaseDebitClient extends JFrame
implements ActionListener
{

3. Define a JTextField, JButton, Jlabel, and a String for the user interface.
4. Create a reference to the PurchaseDebitEJB, as shown in Listing 4-5:

Listing 4-5: Creating the Components

// Creating UI components
JTextField amount = new JTextField(10);
JButton debitValue = new JButton("Debit Amount");
JButton showBalance = new JButton("Get Balance");
// Declaring a label that displays current status to the user
JLabel status;
String msg = "Debit Balance: ";
// Declaring a variable that will hold a reference to the beans remote interface
PurchaseDebit bean;

5. Define a constructor for the class, and provide a title for the JFrame, using the code:
public PurchaseDebitClient()
{
super("Purchase Card Value $5000");
}
6. Create a main method, and initialize the PurchaseDebitClient JFrame, as:
public static void main(String args[])
{
new PurchaseDebitClient().init();
}
7. Define an init() method to invoke a user-defined method called buildGUI() that generates the user interface for the client.

8. Implement code to close the client application window, when the end user clicks the close icon.
9. Register the PurchaseDebitClient class to receive action event notifications, as shown in Listing 4-6:

Listing 4-6: Using init() Method

// Used to build the UI and registers UI components to receive event notifications


public void init()
{
buildGUI();
setDefaultCloseOperation(EXIT_ON_CLOSE);
debitValue.addActionListener(this);
showBalance.addActionListener(this);
createPurchaseDebit();
setVisible(true);
}

Creating the GUI

Page 8 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

You need to create the GUI for this application as a JFrame. Place the components in the JFrame and also specify a layout. To create the GUI:
1. Define a method called buildGUI to specify the layout and elements in the JFrame.

2. Set the size of the JFrame.

3. Create a GridBagConstraints and GridBagLayout objects.


4. Set GridBagLayout as the layout of the JFrame, as:
// This method makes use of Swing components to build the UI
public void buildGUI()
{
setSize(350,180);
GridBagLayout gl = new GridBagLayout();
GridBagConstraints gc = new GridBagConstraints();
Container container = getContentPane();
container.setLayout(gl);
5. Specify the gridwidth value.
6. Create a JLabel in the client application window.

7. Set constraints for the label and add it to the JFrame, using the code:
gc.gridwidth = GridBagConstraints.REMAINDER;
JLabel head = new JLabel("DEBIT CARD TRANSACTION");
gl.setConstraints(head,gc);
container.add(head);
8. Specify a gridwidth value and add a label.

9. Set constraints for the label, and add it to the JFrame, as:
gc.gridwidth = GridBagConstraints.BOTH;
JLabel label = new JLabel(" Enter Amount ");
gl.setConstraints(label,gc);
container.add(label);
10. Specify the gridwidth value to add the Jbuttons, debitValue, showBalance, and the String called status.

11. Position the elements in the client application window, using the code:
gc.gridwidth = GridBagConstraints.REMAINDER;
gl.setConstraints(amount,gc);
container.add(amount);

Invoking the Bean Method

You need to write a method in the client class to access the JNDI service and perform a lookup. The JNDI service returns a reference to a
PurchaseDebitHome interface. Invoke the create method using this reference. To invoke the bean method:
1. Define a method called createPurchaseDebit() to access the JNDI service and obtain a reference to the EJBHome implementation.

2. Create a reference to an InitialContext object.


3. Perform a lookup using the JNDI name of the bean.

4. Narrow the reference to a specific EJBHome object, called PurchaseDebitHome.

5. Invoke the create() method and pass 5000 as parameter to the create() method, using the code:
/* This method is called immediately after building UI and obtains a reference to
/* the beans remote object. */
public void createPurchaseDebit()
{
try
{
InitialContext initial = new InitialContext();
Object objRef = initial.lookup("PurchaseDebit");
PurchaseDebitHome home = (PurchaseDebitHome)
PortableRemoteObject.narrow(objRef,PurchaseDebitHome.class);
bean = home.create(5000);
}
catch(NamingException ne)
{
System.out.println(ne.getMessage());
}
catch(RemoteException re)

Page 9 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

{
System.out.println(re.getMessage());
}
catch(CreateException ce)
{
System.out.println(ce.getMessage());
}
}
6. Define an actionPerformed method to obtain the value entered by the end user, and convert it into a java.lang.Double datatype.

7. Assign it as parameter to the debitValue() method of the bean and check if the end user has clicked the Get Balance button, as:
/* This method receives event notifications upon user interaction with UI components.
/* Based on the component that fired the event, the respective business methods of
/* The bean are invoked. */
public void actionPerformed(ActionEvent ae)
{
String str = amount.getText();
if(str.equals(""))
{
return;
}
if(ae.getSource() == debitValue)
{
try
{
bean.debitValue(Double.parseDouble(str));
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
}
if(ae.getSource() == showBalance)
{
8. Invoke the getbalance() method on the bean.
9. Display the balance in the status string, as:
try
{
double balance = bean.getBalance();
status.setText(msg + balance);
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
}
}
}

Listing 4-7 shows the PurchaseDebitClient class:

Listing 4-7: The PurchaseDebitClient.java File

// Import necessary packages


import purchaseDebit.PurchaseDebitHome;
import purchaseDebit.PurchaseDebit;
import java.awt.*;
import java.awt.event.*;
import java.rmi.*;
import javax.rmi.PortableRemoteObject;
import javax.naming.*;
import javax.swing.*;
import javax.ejb.CreateException;
// The client class that provides Swing component based UI
public class PurchaseDebitClient extends JFrame
implements ActionListener

Page 10 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

{
// Creating UI components
JTextField amount = new JTextField(10);
JButton debitValue = new JButton("Debit Amount");
JButton showBalance = new JButton("Get Balance");
// Declaring a label that displays current status to the user
JLabel status;
String msg = "Debit Balance: ";
// Declaring a variable that will hold a reference to the beans remote interface
PurchaseDebit bean;
public PurchaseDebitClient()
{
super("Purchase Card Value $5000");
}
public static void main(String args[])
{
new PurchaseDebitClient().init();
}
// Used to build the UI and registers UI components to receive event notifications
public void init()
{
buildGUI();
setDefaultCloseOperation(EXIT_ON_CLOSE);
debitValue.addActionListener(this);
showBalance.addActionListener(this);
createPurchaseDebit();
setVisible(true);
}
// This method makes use of Swing components to build the UI
public void buildGUI()
{
setSize(350,180);
GridBagLayout gl = new GridBagLayout();
GridBagConstraints gc = new GridBagConstraints();
Container container = getContentPane();
container.setLayout(gl);
gc.gridwidth = GridBagConstraints.REMAINDER;
JLabel head = new JLabel("DEBIT CARD TRANSACTION");
gl.setConstraints(head,gc);
container.add(head);
gc.gridwidth = GridBagConstraints.BOTH;
JLabel label = new JLabel(" Enter Amount ");
gl.setConstraints(label,gc);
container.add(label);
gc.gridwidth = GridBagConstraints.REMAINDER;
gl.setConstraints(amount,gc);
container.add(amount);
gl.setConstraints(debitValue,gc);
container.add(debitValue);
gl.setConstraints(showBalance,gc);
container.add(showBalance);
status = new JLabel(msg);
gl.setConstraints(status,gc);
container.add(status);
}
/* This method is called immediately after building UI and obtains a reference to
the beans remote object. */
public void createPurchaseDebit()
{
try
{
InitialContext initial = new InitialContext();
Object objRef = initial.lookup("PurchaseDebit");
PurchaseDebitHome home = (PurchaseDebitHome)
PortableRemoteObject.narrow(objRef,PurchaseDebitHome.class);
bean = home.create(5000);
}
catch(NamingException ne)
{

Page 11 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

System.out.println(ne.getMessage());
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
catch(CreateException ce)
{
System.out.println(ce.getMessage());
}
}
/* This method receives event notifications upon user interaction with UI components.
Based on the component that fired the event, the respective business methods of
the bean are invoked. */
public void actionPerformed(ActionEvent ae)
{
String str = amount.getText();
if(str.equals(""))
{
return;
}
if(ae.getSource() == debitValue)
{
try
{
bean.debitValue(Double.parseDouble(str));
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
}
if(ae.getSource() == showBalance)
{
try
{
double balance = bean.getBalance();
status.setText(msg + balance);
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
}
}
}

Deploying the Stateful Session Bean


To deploy an EJB in an application server you must set the environment variables. You also need to configure the deployment descriptor file to
deploy the PurchaseDebitEJB bean. Listing 4-8 shows the deployment descriptor file, ejb-jar.xml, configured to deploy the PurchaseDebitEJB
bean:

Listing 4-8: The ejb-jar.xml file

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<display-name>PurchaseDebitJAR</display-name>
<enterprise-beans>
<session>
<display-name>PurchaseDebitBean</display-name>
<ejb-name>PurchaseDebit</ejb-name>
<home>purchaseDebit.PurchaseDebitHome</home>
<remote>purchaseDebit.PurchaseDebit</remote>
<ejb-class>purchaseDebit.PurchaseDebitEJB</ejb-class>
<session-type>Stateful</session-type>

Page 12 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>

Creating the build.xml File


You need to create a build.xml file for the application build tool called Another Neat Tool (ANT). ANT uses the build.xml file to compile the
stateful session bean, and create deployment directories. ANT also packages the class files and the deployment descriptor file into a JAR file.
The build.xml file performs various tasks, such as:
1. Creates the directory structure build/META-INF.
2. Compiles all the .java files and stores the EJB source files under the build\purchaseDebit folder and the client source files under the
build directory.
3. Copies the ejb-jar.xml file to the build/META-INF directory.

4. Copies the jndi.properties file to the build directory. The jndi.properties file specifies the JNDI service provider required by the client
application to access the EJB.

5. Packages the contents of the build directory as a JAR file. The file is stored in the jboss-3.2.1/server/default/deploy directory.
Listing 4-9 shows the build.xml file for creating a stateful session bean:

Listing 4-9: The build.xml File

<project name="Deploying a ejb" default="jar" basedir=".">


<target name="init"
description="Initializes properties that are used by the other targets. ">
<tstamp/>
<property name="build" value="/home/stateful" />
</target>
<target name="prepare" depends="init"
description="Creates META-INF directory" >
<echo message="Creating META-INF directory ..." />
<mkdir dir="${build}/build/META-INF" />
</target>
<target name="compile" depends="prepare"
description="Compiles source code">
<echo message="Compiling source code ..."/>
<javac
srcdir="${build}"
destdir="${build}/build"
includes="*.java"/>
</target>
<target name="copy" depends="compile">
<echo message="Copying ejb-jar.xml file to META-INF directory ..."/>
<copy
file="ejb-jar.xml"
todir="${build}/build/META-INF"
overwrite="yes"/>
<echo message="Copying jndi.properties file to build directory ..."/>
<copy
file="jndi.properties"
todir="${build}/build"
overwrite="yes"/>
</target>
<target name="jar" depends="copy">
<echo message="Creating JAR file "/>
<jar destfile="/usr/java/jboss-3.2.1/server/default/deploy/stateful.jar"
basedir="${build}/build"
excludes="PurchaseDebitClient*.class,*.properties"/>
</target>
</project>

Setting the Environment Variables

Page 13 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

This application is deployed in JBoss 3.2.1 installed on Linux 8.0 operating system. To deploy the stateful session bean, you must set the
environment variables that enable access to the executables, such as the javac compiler, ANT tool, and JBoss script files. To set the
environment variables:
1. Set the JBOSS_HOME environment variable to the JBoss installation directory path using the command:
JBOSS_HOME=/usr/java/jboss-3.2.1
2. Export the JBOSS_HOME environment variable using the command:
export JBOSS_HOME
3. Set the JAVA_HOME environment variable to the Java installation directory using the command:
JAVA_HOME=/usr/java/j2sdk1.4.1_01
4. Export the JAVA_HOME environment variable using the command:
export JAVA_HOME
5. Set the path to run java commands:
PATH=$PATH:$JAVA_HOME/bin
6. Export the PATH environment variable using the command:
export PATH
7. Set the CLIENT_CLASSES user-defined variable to the client directory under JBoss, as:
CLIENT_CLASSES=$JBOSS_HOME/client
8. Export the CLIENT_CLASSES user-defined variable using the command:
export CLIENT_CLASSES
9. Set the class path for other classes in the JBOSS directory, as:
export CLASSPATH=$CLASSPATH:$CLIENT_CLASSES/jboss-j2ee.jar:$CLIENT_CLASSES/log4j.jar:
$CLIENT_CLASSES/jboss-common-client.jar:$CLIENT_CLASSES/jboss-system-client.jar:
$CLIENT_CLASSES/jnp-client.jar:$CLIENT_CLASSES/jboss-client.jar:
$CLIENT_CLASSES/jbossall-client.jar:.
10. Export the classpath environment variable using the command:
export CLASSPATH

Deploying the JAR


To deploy the stateful session bean application, you need to start JBoss, and build the application, using ANT. The JAR created from the build
process is placed in the deploy directory of the JBoss installation for deployment.
To deploy the application:
1. Start the JBoss server from the terminal command line using the command:
sh run.sh
2. Change to the /root/jboss directory where the build.xml file is saved.
3. Invoke the ANT tool, using the command:
ant

Figure 4-2 shows the build process of the stateful.jar file using the ANT tool:

Page 14 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

Figure 4-2: Building the stateful.jar File

4. Change to the JBoss terminal window to view the deployment of the JAR file. Figure 4-3 shows the output in the terminal window:

Figure 4-3: Terminal Window with JBoss Server Running

5. Launch a terminal window and invoke the client using the command:
java PurchaseDebitClient

Figure 4-4 shows the debit card transaction form that appears:

Page 15 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

Figure 4-4: Debit Card Transaction Form

6. Specify an amount in the Enter Amount text box, and click Debit Amount, as shown in Figure 4-5:

Figure 4-5: Entering the Amount

7. Click Get Balance to view the balance. Figure 4-6 shows the account balance information:

Figure 4-6: Displaying the Balance Amount

Creating a Stateless Session Bean


You can create a stateless session bean to calculate simple interest, and deploy it on the JBoss server. A stateless session bean consists of a
home and a remote interface, and a SimpleInterestEJB class.

Creating the Home Interface


The home interface of the SimpleInterestEJB bean defines a create() method. The EJB container invokes the create() method to create an
EJBHome instance. The EJBHome instance is the remote representation of the session bean. The SimpleInterestHome class is the home
interface for the SimpleInterestEJB bean. To create the SimpleInterestHome class:
1. Import all the required Java packages.
2. Create an interface called SimpleInterestHome that extends the EJBHome interface.
Listing 4-10 shows the home interface called SimpleInterestHome:

Listing 4-10: The SimpleInterestHome Interface

package simpleInterest;
// Import necessary packages
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import java.rmi.RemoteException;
public interface SimpleInterestHome extends EJBHome
{
// The create() method for SimpleInterestEJB bean

Page 16 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

SimpleInterest create() throws RemoteException, CreateException;


}

Creating the Remote Interface


The remote interface extends the EJBObject interface and defines the business methods of the session bean that are invoked by the client.
These methods are implemented by the SimpleInterestEJB session bean. The methods of the EJBObject interface are implemented by the
EJB container, which provides a remote object representing the SimpleInterestEJB bean. The SimpleInterest class is the remote interface for
the SimpleInterestEJB bean. To create the SimpleInterest class:
1. Import the required Java packages.

2. Create an interface, called SimpleInterest, which extends the EJBObject interface.


Listing 4-11 shows the remote interface called SimpleInterest:

Listing 4-11: The SimpleInterest.java File

package simpleInterest;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface SimpleInterest extends EJBObject
{
// Declaring business methods that will be invoked by client
public double calculateSimpleInterest(double principal,double noOfYears,
double rateOfInterest)
throws RemoteException;
}

Creating the Session Bean Class


The session bean implements the abstract business methods of the remote interface and the SessionBean interface. The EJB container
invokes the methods of the SessionBean interface to access an EJB. Clients invoke the business methods of an EJB to calculate the simple
interest for a specified amount. SimpleInterestEJB is the bean class, which implements business methods. To create the SimpleInterestEJB
class:
1. Import all the required Java packages.
2. Create a class called SimpleInterestEJB that implements the SessionBean interface.
Listing 4-12 shows the implementation class:

Listing 4-12: The SimpleIntereseEJB.java File

package simpleInterest;
import javax.ejb.*;
public class SimpleInterestEJB implements SessionBean
{
public void ejbActivate()
{
}
public void ejbPassivate()
{
}
public void ejbRemove()
{
}
public void setSessionContext(SessionContext ctx)
{
}
public void ejbCreate()
{
}
// Implementation of business method declared in the beans remote interface
public double calculateSimpleInterest(double principal,double noOfYears,double rateOfIntere
{
double simpleInterest = 0;

Page 17 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

simpleInterest = principal * noOfYears * rateOfInterest / 100;


return simpleInterest;
}
}

Creating the Client Class


The session bean client invokes the session bean methods using the services provided by JBoss. These services include obtaining
references to the EJBHome and EJBObject interfaces. The client for the SimpleInterestEJB bean is a console application called
SimpleInterestClient. To create the SimpleInterestClient class:
1. Import the necessary packages.
2. Create a class called SimpleInterestClient.
3. Create instances of the home and the remote interfaces of the SimpleInterestEJB bean.

4. Provide the values of principal, no of years, and rate of interest to the SimpleInterest class to calculate the simple interest.
Listing 4-13 shows the Client class:

Listing 4-13: The Client Class

// Import necessary packages


import javax.ejb.*;
import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import simpleInterest.SimpleInterestHome;
import simpleInterest.SimpleInterest;
public class SimpleInterestClient
{
public static void main(String args[])
{
try
{
// Get a naming context object
InitialContext ctx = new InitialContext();
// Get a reference to the beans JNDI entry
Object objRef = ctx.lookup("SimpleInterest");
// Get a reference to the beans home interface
SimpleInterestHome home = (SimpleInterestHome)
PortableRemoteObject.narrow(objRef,SimpleInterestHome.class);
// Get a reference to the beans remote interface by calling create() method
SimpleInterest bean = home.create();
// Invoke the beans business methods
System.out.println(bean.calculateSimpleInterest(100000,2,18));
}
catch(NamingException ne)
{
System.out.println(ne.getMessage());
}
catch(CreateException ce)
{
System.out.println(ce.getMessage());
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
}
}

Deploying the Stateless Session Bean


To deploy the SimpleInterestEJB bean, you need to create a deployment descriptor file. You need to use the ANT tool to compile the classes,

Page 18 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

create deployment directories in the JBoss installation directory, and package the compiled classes and deployment descriptor file into a JAR
file. Follow the process explained for deploying the stateful session bean to perform these tasks.

Creating the Deployment Descriptor File


The Deployment Descriptor for the stateless session bean needs to specify the session type as stateless. You need to add stateless as the
content of the session-type child element in the session element.
Listing 4-14 shows the deployment descriptor for the SimpleInterestEJB bean:

Listing 4-14: Deployment Descriptor for SimpleInterestEJB Bean

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<description>Simple stateless session bean to calculate yearly simple interest</description>
<display-name>Simple Interest Bean</display-name>
<enterprise-beans>
<session>
<description>Session bean to calculate yearly simple interest</description>
<display-name>Interest Bean</display-name>
<ejb-name>SimpleInterest</ejb-name>
<home>simpleInterest.SimpleInterestHome</home>
<remote>simpleInterest.SimpleInterest</remote>
<ejb-class>simpleInterest.SimpleInterestEJB</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
</ejb-jar>

Creating a Container Managed Persistent Bean


You can create a customer entity bean to insert customer information into a database and retrieve this information from the database. The
database calls to insert and view customer information is provided by the EJB container, and not by the entity bean. Before you create a CMP,
you need to create the home interface.

Creating the Customer Home Interface


You can create a home interface called CustomerHome that extends the EJBHome interface. The CustomerHome class is the home interface
for the Customerbean bean. To create the CustomerHome class:
1. Import all the required Java packages.
2. Create a class called CustomerHome that extends the EJBHome interface.
Listing 4-15 shows the CustomerHome class:

Listing 4-15: The CustomerHome.java File

package valueObject;
// Import necessary packages
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import javax.ejb.FinderException;
import java.rmi.RemoteException;
// The beans home interface
public interface CustomerHome extends EJBHome
{
// create method for the CustomerEJB bean
public Customer create(String customerID,String customerName,AddressValueObject address)
throws RemoteException,CreateException;
// Declaring the required finder method for the CustomerEJB bean
public Customer findByPrimaryKey(String customerID)
throws RemoteException,FinderException;
}

Page 19 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

Creating the Customer Remote Interface


After creating the home interface, you need to create the remote interface. To do so, create the Customer class that extends the EJBObject
interface. The Customer class represents the object interface for the CustomerBean bean. To create the customer class:
1. Import the required Java packages.
2. Create a class called Customer that extends the EJBObject interface.
Listing 4-16 shows the Customer class:

Listing 4-16: The Customer.java File

package valueObject;
// Import necessary packages
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
// Declaring the remote interface for CustomerEJB bean
public interface Customer extends EJBObject
{
// Declaring the CustomerEJB beans business methods
public String getCustomerName() throws RemoteException;
public AddressValueObject getAddress() throws RemoteException;
}

Creating the Customer Implementation Class


After creating the remote interface, you need to create the implementation class. You can create a class called CustomerBean that
implements the EntityBean interface. To create the CustomerBean:
1. Import all the required Java packages.
2. Create a class called CustomerBean that implements the EntityBean interface.
3. Declare the methods of the CustomerBean class.

Listing 4-17 shows the CustomerBean class:

Listing 4-17: The CustomerBean.java File

package valueObject;
import javax.ejb.*;
import javax.naming.*;
public abstract class CustomerBean implements EntityBean
{
//CMP fields used for persistence
public abstract String getCustomerID();
public abstract void setCustomerID(String customerID);
public abstract String getCustomerName();
public abstract void setCustomerName(String customerName);
public abstract AddressLocal getAddress();
public abstract void setAddress(AddressLocal address);
public AddressValueObject getAddressView()
{
AddressLocal address = getAddress();
return new AddressValueObject(address.getAddressID(),address.getStreet(),
address.getCity(),address.getState(),address.getZip());
}
// ejbCreate method that creates a entity bean and a record in the persistent datastore
public String ejbCreate(String customerID,String customerName,AddressValueObject address)
throws CreateException
{
setCustomerID(customerID);
setCustomerName(customerName);
return null;
}
// This method can be used for further initialization after the entity bean is created.

Page 20 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

public void ejbPostCreate(String customerID, String customerName,


AddressValueObject addressView)
throws CreateException
{
AddressLocal address = createAddress(addressView.getAddressID(), addressView.getStreet(),
addressView.getCity(), addressView.getState(), addressView.getZip());
setAddress(address);
}
private AddressLocal createAddress(String addressID,String street,String city,String state,Strin
{
try
{
InitialContext ctx = new InitialContext();
AddressLocalHome home = (AddressLocalHome)ctx.lookup("java:comp/env/ejb/AddressEJB");
return home.create(addressID,street,city,state,zip);
}
catch(Exception e)
{
throw new javax.ejb.EJBException(e);
}
}
// The ejb methods whose implementation will be provided by the EJB container
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbLoad() {}
public void ejbRemove() {}
public void ejbStore() {}
public void setEntityContext(EntityContext ctx){}
public void unsetEntityContext() {}
}

Creating the Address Entity Bean


You can create an Address entity bean to persist the address information about the customer. This Address entity bean is also created as a
CMP entity bean. This entity bean uses a ValueObject class to represent address information.

Creating the Address Value Object Class

Create a class called ValueObject that contains the getter and setter methods for the variables declared in the class. You can create the
AddressValueObject class that implements the serializable interface, and represents the data that has to be displayed. To create the
AddressValueObject class:
1. Import all the required Java packages.
2. Create a class called AddressValueObject that implements the serializable interface.
3. Declare all the required variables.

4. Declare the setter and getter methods for the variables declared.
Listing 4-18 shows the AddressValueObject class:

Listing 4-18: The AddressValueObject.java File

/* Writing the value object class that will be used by CustomerEJB bean. */
package valueObject;
import java.io.Serializable;
public class AddressValueObject implements Serializable
{
private int addressID;
private String street;
private String city;
private String state;
private String zip;
public AddressValueObject() {}
public AddressValueObject(int addressID,String street,String city,String state,String zip)
{
this.addressID = addressID;
this.street = street;

Page 21 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

this.city = city;
this.state = state;
this.zip = zip;
}
public int getAddressID()
{
return addressID;
}
public void setAddressID(int addressID)
{
this.addressID = addressID;
}
public String getStreet()
{
return street;
}
public void setStreet(String street)
{
this.street = street;
}
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
public String getState()
{
return state;
}
public void setState(String state)
{
this.state = state;
}
public String getZip()
{
return zip;
}
public void setZip(String zip)
{
this.zip = zip;
}
}

Creating the Address Home Interface

You can create a home interface called AddressLocalHome that extends the EJBLocalHome interface. The AddressLocalHome class is the
local home interface for the AddressBean entity bean. To create the AddressLocalHome class:
1. Import all the required Java packages.
2. Create a class called AddressLocalHome that extends the EJBLocalHome interface.

Listing 4-19 shows the AddressLocalHome class:

Listing 4-19: The AddressLocalHome Class

package valueObject;
import javax.ejb.EJBLocalHome;
import javax.ejb.CreateException;
import javax.ejb.FinderException;
public interface AddressLocalHome extends EJBLocalHome
{
public AddressLocal create(String addressID,String street,String city,String state,String zi
throws CreateException;
public AddressLocal findByPrimaryKey(String addressID)

Page 22 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

throws FinderException;
}

Creating the Address Remote Interface

After creating the local home interface, you need to create the local remote interface. To do so, create the AddressLocal class that extends the
EJBLocalObject interface. The AddressLocal interface represents the object interface for the AddressBean bean. To create the AddressLocal
interface:
1. Import the required Java package.

2. Create an interface called AddressLocal that extends the EJBLocalObject interface.


Listing 4-20 shows the AddressLocal interface:

Listing 4-20: The AddressLocal Interface

package valueObject;
import javax.ejb.EJBLocalObject;
public interface AddressLocal extends EJBLocalObject
{
public String getAddressID();
public String getStreet();
public void setStreet(String street);
public String getCity();
public void setCity(String city);
public String getState();
public void setState(String state);
public String getZip();
public void setZip(String zip);
}

Creating the Address Implementation Class

After creating the local remote interface, you need to create the implementation class. You can create a class called AddressBean that
implements the EntityBean interface. To create the AddressBean:
1. Import all the required Java packages.

2. Create a class called AddressBean that implements the EntityBean interface.


3. Declare all the methods.

Listing 4-21 shows the AddressBean class:

Listing 4-21: The AddressBean Class

package valueObject;
import javax.ejb.EntityBean;
import javax.ejb.CreateException;
import javax.ejb.EntityContext;
public abstract class AddressBean implements EntityBean
{
// Declare CMP files to be persisted
public abstract String getAddressID();
public abstract void setAddressID(String addressID);
public abstract String getStreet();
public abstract void setStreet(String street);
public abstract String getCity();
public abstract void setCity(String city);
public abstract String getState();
public abstract void setState(String state);
public abstract String getZip();
public abstract void setZip(String zip);
// Declare the ejbCreate method that creates an entity bean and a record in the
persistent datastore
public String ejbCreate(String addressID, String street, String city,

Page 23 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

String state, String zip)


throws CreateException
{
setAddressID(addressID);
setStreet(street);
setCity(city);
setState(state);
setZip(zip);
return null;
}
// Declare other necessary callback methods
public void ejbPostCreate(String addressID, String street,
String city, String state, String zip)
throws CreateException
{
}
public void ejbActivate()
{
}
public void ejbLoad()
{
}
public void ejbPassivate()
{
}
public void ejbRemove()
{
}
public void ejbStore()
{
}
public void setEntityContext(EntityContext ctx)
{
}
public void unsetEntityContext()
{
}
}

Creating the Customer Client Class


Create the client class called CustomerClient to retrieve information from the EJB. To create the CustomerClient class:
1. Import all the required Java packages.
2. Create a class called CustomerClient.

Listing 4-22 contains the code for the CustomerClient class:

Listing 4-22: The CustomerClient.java File

// Import necessary packages


import valueObject.CustomerHome;
import valueObject.Customer;
import valueObject.CustomerBean;
import valueObject.AddressValueObject;
import javax.rmi.PortableRemoteObject;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.RemoveException;
public class CustomerClient
{
public static void main(String arg[])
{
try
{

Page 24 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

// Get a reference to a jndi context


InitialContext ctx = new InitialContext();
/* Get a reference to the beans home interface by searching for the beans jndi entry.
Object objRef = ctx.lookup("ValueObjectCustomerEJB");
CustomerHome home = (CustomerHome)
PortableRemoteObject.narrow(objRef,CustomerHome.class);
// Create an entity bean by calling create() method on the home interface
Customer customer = home.create("1","Michael Dane", new AddressValueObject(111,
"NY Lane","AppleValley","California","93207"));
// Invoke business methods on the beans remote interface
System.out.println(customer.getCustomerName());
AddressValueObject address = customer.getAddress();
System.out.println(address.getStreet());
System.out.println(address.getCity());
System.out.println(address.getState());
System.out.println(address.getZip());
customer.remove();
}
catch(NamingException ne)
{
System.out.println(ne.getMessage());
}
catch(CreateException ce)
{
System.out.println(ce.getMessage());
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
catch(RemoveException re)
{
System.out.println(re.getMessage());
}
}
}

Creating the Deployment Descriptor File


To deploy an EJB in an application server, you must set the environment variables. You must write the deployment descriptor file to deploy the
CustomerBean bean. Listing 4-23 shows the deployment descriptor file, ejb-jar.xml, for the CustomerBean bean:

Listing 4-23: The ejb-jar.xml File for the CustomerBean

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<entity>
<display-name>ValueObjectCustomerEJB</display-name>
<ejb-name>ValueObjectCustomerEJB</ejb-name>
<home>valueObject.CustomerHome</home>
<remote>valueObject.Customer</remote>
<ejb-class>valueObject.CustomerBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>True</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>ValueObjectCustomerBean</abstract-schema-name>
<cmp-field>
<field-name>customerID</field-name>
</cmp-field>
<cmp-field>
<field-name>customerName</field-name>
</cmp-field>
<primkey-field>customerID</primkey-field>
<ejb-local-ref>

Page 25 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

<ejb-ref-name>ejb/AddressEJB</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>valueObject.AddressLocalHome</local-home>
<local>valueObject.AddressLocal</local>
<ejb-link>AddressEJB</ejb-link>
</ejb-local-ref>
</entity>
<entity>
<display-name>AddressEJB</display-name>
<ejb-name>AddressEJB</ejb-name>
<local-home>valueObject.AddressLocalHome</local-home>
<local>valueObject.AddressLocal</local>
<ejb-class>valueObject.AddressBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>True</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>AddressBean</abstract-schema-name>
<cmp-field><field-name>addressID</field-name></cmp-field>
<cmp-field><field-name>street</field-name></cmp-field>
<cmp-field><field-name>city</field-name></cmp-field>
<cmp-field><field-name>state</field-name></cmp-field>
<cmp-field><field-name>zip</field-name></cmp-field>
<primkey-field>addressID</primkey-field>
</entity>
</enterprise-beans>
<relationships>
<ejb-relation>
<ejb-relation-name>Customer - Address</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>
ValueObjectCustomerEJB
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>
ValueObjectCustomerEJB
</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>address</cmr-field-name>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>
AddressEJB
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>AddressEJB</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>
</relationships>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>ValueObjectCustomerEJB</ejb-name>
<method-name>*</method-name>
</method>
<method>
<ejb-name>AddressEJB</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

Page 26 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

Creating the build.xml File for CustomerBean


You need to create the build.xml file to compile the CustomerBean entity bean, and create deployment directories, using the ANT tool. The
ANT tool also packages the class files, and the deployment descriptor file into a JAR file. The tasks performed by the build.xml file are:
1. Creates the directory structure build/META-INF.
2. Compiles all the .java files and stores the EJB source files under the buil\purchaseDebit folder and the client source files under the build
directory.
3. Copies the ejb-jar.xml file to the build/META-INF directory.
4. Copies the jndi.properties file to the build directory.
5. Packages the contents of the build directory as a JAR file. The file is stored in the jboss-3.2.1/server/default/deploy directory.
Listing 4-24 shows the build.xml for the CMP entity bean:

Listing 4-24: The build.xml File

<project name="Deploying a ejb" default="jar" basedir=".">


<target name="init"
description="Initializes properties that are used by the other targets. ">
<tstamp/>
<property name="build" value="="/home/cmp" />
</target>
<target name="prepare" depends="init"
description="Creates META-INF directory" >
<echo message="Creating META-INF directory ..." />
<mkdir dir="${build}/build/META-INF" />
</target>
<target name="compile" depends="prepare"
description="Compiles source code">
<echo message="Compiling source code ..."/>
<javac
srcdir="${build}"
destdir="${build}/build"
includes="*.java"/>
</target>
<target name="copy" depends="compile">
<echo message="Copying ejb-jar.xml file to META-INF directory ..."/>
<copy
file="ejb-jar.xml"
todir="${build}/build/META-INF"
overwrite="yes"/>
<echo message="Copying jndi.properties file to build directory ..."/>
<copy
file="jndi.properties"
todir="${build}/build"
overwrite="yes"/>
</target>
<target name="jar" depends="copy">
<echo message="Creating JAR file "/>
<jar destfile="/usr/java/jboss-3.2.1/server/default/deploy/cmp.jar"
basedir="${build}/build"
excludes="CustomerClient*.class,*.properties" />
</target>
</project>

Deploying the JAR File


To deploy the CMP entity bean, you need to launch the JBoss server, and build the application using the ANT tool. The JAR created from the
build process is placed in the deploy directory of the JBoss installation. The JBoss server deploys the JAR. To deploy the application:
1. Start the JBoss server from the terminal command line, using the command:
sh run.sh
2. Change to the /root/jboss directory where you saved the build.xml file.

Page 27 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

3. Invoke the ANT tool using the command:


ant

All the class files are grouped as a single JAR file, and then deployed on the JBoss server. The class files for the ProductBean are
grouped as the cmp.jar file. The Java archives have the extension as .jar. Figure 4-7 shows the build process of the cmp.jar file with the
ANT tool:

Figure 4-7: Building the cmp.jar File Using the ANT Tool

4. Change to the JBoss terminal window. Figure 4-8 shows the output in the terminal window:

Page 28 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

Figure 4-8: The Terminal Window

5. Open a terminal window and invoke the client, using the command:
java CustomerClient

Figure 4-9 shows the output of the CustomerClient class:

Figure 4-9: The CustomerClient Class

Creating a Bean Managed Persistent Bean


You can create a BMP bean that enables you to enter records to, and retrieve records from a database, and deploy the bean on the JBoss
server.

Creating the ProductHome Interface


The home interface of the ProductBean bean defines the methods used to retrieve records from the database, update records to the table,
and to create a table. The home interface also defines methods to delete a table or a record. The ProductHomeRemote class is the home
interface for the ProductBean bean. To create the ProductHomeRemote class:
1. Import all the required Java packages.

2. Create a class called ProductHomeRemote that extends the EJBHome interface.


Listing 4-25 shows the ProductHomeRemote class:

Listing 4-25: Creating the ProductHomeRemote.java File

/* Home interface for the BMP managed Entity Bean.*/


package bmp;
// Import necessary packages
import java.util.Collection;
import java.rmi.RemoteException;
import javax.ejb.EJBHome;
import javax.ejb.CreateException;
import javax.ejb.FinderException;
public interface ProductHomeRemote extends EJBHome
{
// Declaring create() method that will create the BMP entity bean
public ProductRemote create(Integer productID,String productName,double price)
throws RemoteException,CreateException;
// Declaring the required finder methods
public ProductRemote findByPrimaryKey(Integer productID)
throws RemoteException,FinderException;
public Collection findInRange(double lowerPrice,double higherPrice)
throws RemoteException,FinderException;
// Declaring methods that will be used to create a table for the persisting data
public void makeTable() throws RemoteException;
public void deleteTable() throws RemoteException;
}

Creating the ProductRemote Interface


The remote interface extends the EJBObject interface, and defines the business methods for the bean that are implemented by the
ProductBean bean. The EJB container implements the methods present in the EJBObject interface that provides a remote object representing

Page 29 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

the ProductBean bean. To create the ProductRemote class:


1. Import all the necessary packages.

2. Create a class called ProductRemote that extends the EJBRemote interface.


3. Declare the business methods.

Listing 4-26 shows the ProductRemote interface:

Listing 4-26: The ProductRemote.java File

/* Remote interface for the BMP managed Entity Bean. */


package bmp;
// Import necessary packages
import java.rmi.RemoteException;
import javax.ejb.EJBObject;
public interface ProductRemote extends EJBObject
{
// Declaring the beans business methods
public void setProductName(String productName)
throws RemoteException;
public String getProductName() throws RemoteException;
public void setPrice(double price) throws RemoteException;
public double getPrice() throws RemoteException;
}

Creating the Bean


The entity bean implements the abstract business methods of the remote interface and the SessionBean interface. The EJB container invokes
the methods of the SessionBean interface to access the bean. Clients invoke the business methods of the bean to enter records to the
database and to retrieve records from the database. To create a BMP bean:
1. Import the javax.rmi, javax.ejb, and java.sql packages.

2. Create a class that implements the EntityBean interface.


3. Initialize a reference to the EntityContext object.
4. Create string variable to represent the productName value.
5. Create variables, such as productID, productName, and price of types, integer, string, and double:
public class ProductBean implements EntityBean
{
private Integer productID;
private String productName;
private double price;
private EntityContext context;

The ejbCreate() Method

The ejbCreate() method of an EJB contains the code to instantiate an EJB object, and inserts records to the database. To create the
ejbCreate() method:
1. Assign productID, productName, and price as parameters to the ejbCreate() method as:
public Integer ejbCreate(Integer productID,String productName,double price)
throws CreateException {
2. Establish connection with the database as:
con = this.getConnection();
3. Perform the SQL INSERT statement as:
ps = con.prepareStatement("INSERT INTO PRODUCT (PRODUCTID,PRODUCTNAME,PRICE) VALUES(?,?,?)");
ps.setInt(1,productID.intValue());
ps.setString(2,productName);
ps.setDouble(3,price);
int record = ps.executeUpdate();
}

Creating the ejbFindByPrimaryKey() Method

Page 30 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

The BMP entity bean implements the ejbFindByPrimaryKey() method to locate the EJB based on the primary key field. When you invoke the
ejbFindByPrimaryKey() method, the EJB is loaded to the memory. To create the ejbFindByPrimaryKey() method:
1. Provide an Instance of the primary key column as a parameter to the method:
public Integer ejbFindByPrimaryKey(Integer productID)
throws FinderException {
2. Establish connection with the database.
3. Use the SQL SELECT statement to retrieve information as:
con = this.getConnection();
ps = con.prepareStatement("SELECT PRODUCTID from PRODUCT WHERE PRODUCTID = ? ");
ps.setInt(1,productID.intValue());
result = ps.executeQuery();

Creating the FindInRange() Method

The BMP entity bean implements the FindInRange() method to locate the EJB between two values. When you invoke the
ejbFindByPrimaryKey() method, the EJB is loaded to the memory. To create the FindInRange() method:
1. Provide the price values as parameters to the FindInRange() method, as shown below:
public Collection ejbFindInRange(double lowerPrice,double higherPrice)
throws FinderException {
Vector keys = null;
2. Establish the connection to the database.

3. Include the SQL SELECT statement with the condition to select the values from the database, as shown below:
con = this.getConnection();
ps = con.prepareStatement("SELECT PRODUCTID FROM PRODUCT WHERE PRICE BETWEEN ? AND ?");
ps.setDouble(1,lowerPrice);
ps.setDouble(2,higherPrice);
result = ps.executeQuery();
keys = new Vector();
while(result.next())
{
keys.addElement(new Integer(result.getInt("PRODUCTID")));
}
return keys;
}

Creating the ejbLoad() Method

The BMP bean implements the ejbLoad() method to select the values based on the primary key. To create the ejbLoad() method:
1. Establish connection with the database.
2. Pass the SQL SELECT statement based on a condition, as shown below.
public void ejbLoad()
{
con = this.getConnection();
ps = con.prepareStatement("SELECT PRODUCTNAME,PRICE FROM PRODUCT WHERE PRODUCTID = ?");
ps.setInt(1,primaryKey.intValue());
result = ps.executeQuery();
if(result.next())
{
this.productID = primaryKey;
this.productName = result.getString("PRODUCTNAME");
this.price = result.getDouble("PRICE");

Creating the ejbStore() Method

The BMP bean implements the ejbStore() method to update the values based on the primary key. To create the ejbStore() method:
1. Establish connection with the database.
2. Pass the SQL UPDATE statement based on a condition, as shown below:
public void ejbStore()
{
con = this.getConnection();
ps = con.prepareStatement("UPDATE PRODUCT SET PRODUCTNAME = ?, PRICE = ? WHERE PRODUCTID = ?
ps.setString(1,this.productName);
ps.setDouble(2,this.price);

Page 31 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

ps.setInt(3,this.productID.intValue());
int update = ps.executeUpdate();
}

Creating the ejbRemove() Method

The BMP bean implements the ejbRemove() method to delete the bean. To create the ejbRemove() method:
1. Establish connection with the database.
2. Pass the SQL DELETE statement, as shown below:
public void ejbRemove()
{
con = this.getConnection();
ps = con.prepareStatement("DELETE FROM PRODUCT WHERE PRODUCTID = ?");
ps.setInt(1,this.productID.intValue());
int remove = ps.executeUpdate();
}

Creating the ejbHomeMakeTable() Method

The BMP bean implements the ejbHomeMakeTable() method to create a table. To create the ejbHomeMakeTable() method:
1. Establish connection with the database.
2. Pass the CREATE TABLE command to create a table, as shown below:
public void ejbHomeMakeTable()
{
con = this.getConnection();
ps = con.prepareStatement
("CREATE TABLE PRODUCT(PRODUCTID INT PRIMARY KEY, PRODUCTNAME CHAR(30),
PRICE DECIMAL (8,2))");
int create = ps.executeUpdate();
}

Creating the ejbHomeDeleteTable() Method

The BMP bean implements the ejbHomeDeleteTable() method to delete the table. To create the ejbHomeDeleteTable() method:
1. Establish connection with the database.

2. Include the SQL DELETE statement, as shown below:


public void ejbHomeDeleteTable()
{
con = this.getConnection();
ps = con.prepareStatement("DROP TABLE PRODUCT");
int drop = ps.executeUpdate();
}

Creating the getConnection() Method

The BMP bean implements the getConnection() method to establish connection with the database. To create the getConnection() method:
1. Create an InitialContext type of object.

2. Store the reference of the InitialContext object in the object of the context interface, as shown below:
private Connection getConnection()
{
try
{
Context jndiCtx = new InitialContext();
DataSource dataSource = (DataSource)jndiCtx.lookup("java:comp/env/jdbc/ProdDB");
con = dataSource.getConnection();
}
catch(Exception e)
{
System.out.println("Exception occurred in getting connection");
}
return con;
}

Listing 4-27 shows the ProductBean class:

Page 32 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

Listing 4-27: The ProductBean Class

/* Bean class for the BMP managed EntityBean. */


package bmp;
// Import necessary packages
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.sql.DataSource;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.ObjectNotFoundException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
import java.util.Collection;
public class ProductBean implements EntityBean
{
// Declare variables used to store date for the EntityBean
private Integer productID;
private String productName;
private double price;
// Declare variable to store the entity beans context.
private EntityContext context;
// Accessor methods.
public void setProductName(String productName)
{
this.productName = productName;
}
public String getProductName()
{
return productName;
}
public void setPrice(double price)
{
this.price = price;
}
public double getPrice()
{
return price;
}
/* Providing implementation for the ejbCreate method that will
create an instance of the BMP managed EntityBean. This method will insert
a record in the datasource. Because you are writing a BMP managed EntityBean,
you will have to hard code all the steps used for inserting data
into the datasource. */
public Integer ejbCreate(Integer productID,String productName,double price)
throws CreateException
{
System.out.println("ejbCreate() ...");
if(productID.intValue() < 1 || productName == null)
{
throw new CreateException("Invalid parameters ... ");
}
this.productID = productID;
this.productName = productName;
this.price = price;
PreparedStatement ps = null;
Connection con = null;
try

Page 33 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

{
con = this.getConnection();
ps = con.prepareStatement("INSERT INTO PRODUCT (PRODUCTID,PRODUCTNAME,PRICE) VALUES(?,?,?)"
ps.setInt(1,productID.intValue());
ps.setString(2,productName);
ps.setDouble(3,price);
int record = ps.executeUpdate();
if(record == 1)
{
System.out.println("Product added successfully to the database ... ");
}
else
{
throw new CreateException("Failed to add Product to database ... ");
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
catch(CreateException ce)
{
System.out.println(ce.getMessage());
}
finally
{
try
{
ps.close();
con.close();
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
}
return productID;
}
public void ejbPostCreate(Integer productID,String productName,double price)
{
}
// Provide implementation for the finder method used to find an
// instance of EntityBean.
public Integer ejbFindByPrimaryKey(Integer productID)
throws FinderException
{
Integer id = null;
System.out.println("ejbFindByPrimaryKey() ... " + productID);
Connection con = null;
PreparedStatement ps = null;
ResultSet result = null;
try
{
con = this.getConnection();
ps = con.prepareStatement("SELECT PRODUCTID from PRODUCT WHERE PRODUCTID = ? ");
ps.setInt(1,productID.intValue());
result = ps.executeQuery();
if(!result.next())
{
throw new ObjectNotFoundException("Cannot find product with id= " + productID);
}
else
{
id = productID;
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());

Page 34 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

}
catch(ObjectNotFoundException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
result.close();
ps.close();
con.close();
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
}
return id;
}
/* Provide implementation for the finder method that will return a collection of
entity beans that satisfies the condition. */
public Collection ejbFindInRange(double lowerPrice,double higherPrice)
throws FinderException
{
Connection con = null;
PreparedStatement ps = null;
ResultSet result = null;
Vector keys = null;
try
{
con = this.getConnection();
ps = con.prepareStatement("SELECT PRODUCTID FROM PRODUCT WHERE PRICE BETWEEN ? AND ?");
ps.setDouble(1,lowerPrice);
ps.setDouble(2,higherPrice);
result = ps.executeQuery();
keys = new Vector();
while(result.next())
{
keys.addElement(new Integer(result.getInt("PRODUCTID")));
}
return keys;
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
result.close();
ps.close();
con.close();
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
}
return keys;
}
// Store the reference to the current context in the EntityContext
reference variable public void setEntityContext(EntityContext ctx)
{
context = ctx;
}
// Used reference to the current context in this method
public void unsetEntityContext()

Page 35 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

{
context = null;
}
// The standard ejb methods
public void ejbActivate()
{
}
public void ejbPassivate()
{
}
/* Provide implementation for this method that is used to view all the data
associated with a particular entity bean. */
public void ejbLoad()
{
Connection con = null;
PreparedStatement ps = null;
ResultSet result = null;
System.out.println("Inside ejbLoad() .....");
Integer primaryKey = (Integer)context.getPrimaryKey();
try
{
con = this.getConnection();
ps = con.prepareStatement("SELECT PRODUCTNAME,PRICE FROM PRODUCT WHERE PRODUCTID = ?");
ps.setInt(1,primaryKey.intValue());
result = ps.executeQuery();
if(result.next())
{
this.productID = primaryKey;
this.productName = result.getString("PRODUCTNAME");
this.price = result.getDouble("PRICE");
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
result.close();
ps.close();
con.close();
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
}
}
/* Provide implementation for this method that will be used to update data
associated with a particular entity bean */
public void ejbStore()
{
PreparedStatement ps = null;
Connection con = null;
try
{
con = this.getConnection();
ps = con.prepareStatement("UPDATE PRODUCT SET PRODUCTNAME = ?, PRICE = ? WHERE PRODUCTID =
ps.setString(1,this.productName);
ps.setDouble(2,this.price);
ps.setInt(3,this.productID.intValue());
int update = ps.executeUpdate();
if(update == 1)
{
System.out.println("ejbStore() .... successful .... ");
}
}

Page 36 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

catch(SQLException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
ps.close();
con.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
}
}
/* Provide implementation for this method that will be used to remove a particular
instance of entity bean. Removing a record will also delete a
record from the datastore. */
public void ejbRemove()
{
Connection con = null;
PreparedStatement ps = null;
try
{
con = this.getConnection();
ps = con.prepareStatement("DELETE FROM PRODUCT WHERE PRODUCTID = ?");
ps.setInt(1,this.productID.intValue());
int remove = ps.executeUpdate();
if(remove == 1)
{
System.out.println("ejb bean removed successfully ... ");
}
else
{
System.out.println("ejbRemove unable to remove bean ... ");
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
ps.close();
con.close();
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
}
}
/* Provide implementation for this method that will be used to create a
table in the datastore. */
public void ejbHomeMakeTable()
{
PreparedStatement ps = null;
Connection con = null;
try
{
con = this.getConnection();
System.out.println("Creating datatable Product .....");
ps = con.prepareStatement("CREATE TABLE PRODUCT(PRODUCTID INT PRIMARY KEY,
PRODUCTNAME CHAR(30), PRICE DECIMAL (8,2))");
int create = ps.executeUpdate();

Page 37 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

System.out.println("Value of : " + create);


if(create == 0)
{
System.out.println("Table created successfully ... ");
}
else
{
System.out.println("Table not created ... ");
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
ps.close();
con.close();
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
}
}
/* Provide implementation for this method that will be used to drop a
table in the datastore. */
public void ejbHomeDeleteTable()
{
PreparedStatement ps = null;
Connection con = null;
try
{
con = this.getConnection();
System.out.println("Dropping table PRODUCT ... ");
ps = con.prepareStatement("DROP TABLE PRODUCT");
int drop = ps.executeUpdate();
if(drop == 0)
{
System.out.println("Table dropped successfully ... ");
}
else
{
System.out.println("Table not dropped ... ");
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
finally
{
try
{
ps.close();
con.close();
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
}
}
// Common method used to get a connection to the underlying datastore
private Connection getConnection()
{
Connection con = null;

Page 38 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

try
{
Context jndiCtx = new InitialContext();
DataSource dataSource = (DataSource)jndiCtx.lookup("java:comp/env/jdbc/ProdDB");
con = dataSource.getConnection();
return con;
}
catch(NamingException ne)
{
System.out.println(ne.getMessage());
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
return con;
}

Creating the ProductClient Class


The entity bean client invokes the entity bean methods using the services provided by the JBoss server. These services include obtaining
references to the EJBHome and EJBObject interfaces. To create the ProductClient:
1. Import all the required Java packages.
2. Create the ProductClient class.
Listing 4-28 shows the ProductClient class:

Listing 4-28: The ProductClient.java File

/* Client class for the BMP managed EntityBean. */


// Import the necessary packages.
import bmp.ProductHomeRemote;
import bmp.ProductRemote;
import java.util.Iterator;
import java.util.Collection;
import javax.ejb.CreateException;
import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;
import javax.naming.InitialContext;
import javax.ejb.FinderException;
import javax.naming.NamingException;
public class ProductClient
{
public static void main(String args[])
{
try
{
// Get a reference to a jndi context
InitialContext ctx = new InitialContext();
// Get a reference to a home interface by a jndi lookup
Object objRef = ctx.lookup("ProductEJB");
// Get a reference to the beans home interface
ProductHomeRemote home = (ProductHomeRemote)
PortableRemoteObject.narrow(objRef,ProductHomeRemote.class);
/* Provide command line options while running the program. */
// This if condition if satisfied create a table in the datastore.
if(args[0].equalsIgnoreCase ("CreateDB"))
{
System.out.println("Creating database table ... ");
home.makeTable();
}
// This if condition if satisfied drops a table in the datastore
else if(args[0].equalsIgnoreCase("DropDB"))
{
System.out.println("Dropping database table ... ");
home.deleteTable();

Page 39 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

}
/* This if condition if satisfied creates an entity bean and inserts
a record in the datastore. */
else if( args[0].equalsIgnoreCase("Insert"))
{
ProductRemote remote = home.create(new Integer(args[1]),args[2],Double.parseDouble(args[
}
// This if condition is used to find a entity bean based on its primary key
else if(args[0].equalsIgnoreCase("Find"))
{
System.out.println("Finding product again ... ");
Integer primaryKey = new Integer(args[1]);
ProductRemote bean = home.findByPrimaryKey(primaryKey);
System.out.println(bean.getProductName());
System.out.println(bean.getPrice());
}
/* This if condition is used to return a collection of entity beans that satisfies the cond
else if(args[0].equalsIgnoreCase("FindRange"))
{
int lowerPrice = Integer.parseInt(args[1]);
int higherPrice = Integer.parseInt(args[2]);
Collection beans = home.findInRange(lowerPrice,higherPrice);
Iterator itr = beans.iterator();
while(itr.hasNext())
{
ProductRemote remote = (ProductRemote)PortableRemoteObject.narrow(itr.next(), ProductRe
ProductRemote bean = home.findByPrimaryKey((Integer)remote.getPrimaryKey());
System.out.print("\n" + " : " + bean.getProductName() + " : " + bean.getPrice());
}
}
else
{
throw new ArrayIndexOutOfBoundsException();
}
}
catch(ArrayIndexOutOfBoundsException ex)
{
System.out.println("Usage : java ProductClient <options> parameters");
System.out.println("options : ");
System.out.println("CreateDB");
System.out.println("DropDB");
System.out.println("Insert <itemcode> <itemname> <price>");
System.out.println("Find <itemcode>");
System.out.println("FindRange <lowerprice> <higherprice>");
}
catch(NamingException ne)
{
System.out.println(ne.getMessage());
}
catch(CreateException ce)
{
System.out.println(ce.getMessage());
}
catch(FinderException fe)
{
System.out.println(fe.getMessage());
}
catch(RemoteException re)
{
System.out.println(re.getMessage());
}
}
}

Creating the Deployment Descriptor File


To deploy the SimpleInterestEJB bean, create a deployment descriptor file. You need to use the ANT tool to compile the classes, create
deployment directories in the JBoss installation directory, and package the compiled classes and deployment descriptor file into a JAR file.

Page 40 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited
Working with JBOSS Application Server

Follow the same process to perform these tasks as explained for deploying the CMP bean. Listing 4-29 shows the deployment descriptor for
the ProductBean class:

Listing 4-29: The Deployment Descriptor for ProductBean Class

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<entity>
<description>
This bean represents a product.
</description>
<ejb-name>ProductEJB</ejb-name>
<home>bmp.ProductHomeRemote</home>
<remote>bmp.ProductRemote</remote>
<ejb-class>bmp.ProductBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>java.lang.Integer</prim-key-class>
<reentrant>False</reentrant>
<security-identity><use-caller-identity/></security-identity>
<resource-ref>
<description>DataSource for the Product database</description>
<res-ref-name>jdbc/ProdDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</entity>
</enterprise-beans>
<assembly-descriptor>
<security-role>
<description>
This role represents everyone who is allowed full access to the Product EJB.
</description>
<role-name>everyone</role-name>
</security-role>
<method-permission>
<role-name>everyone</role-name>
<method>
<ejb-name>ProductEJB</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<container-transaction>
<method>
<ejb-name>ProductEJB</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

Page 41 / 41
Reprinted for OET7P/751897, Accenture SkillSoft, SkillSoft Corporation (c) 2003, Copying Prohibited

You might also like