Web Development With Myeclipse And Jboss Part 2

background image

Web Development with MyEclipse and JBoss – Part 2

Web Development with

MyEclipse and JBoss

Part 2 – Enterprise Java Bean

Development with MyEclipse

The WebStock Case Study

The WebStoThe WebStock Case Study

Study

Module 1

By Karim Djaafar

Senior Consultant

Author of

“Developing J2EE Applications with Eclipse and JBoss

Paris, October 2005

Enterprise Java Bean Development with MyEclipse

background image

Web Development with MyEclipse and JBoss – part 2

About the author

The series J2EE development with MyEclipse and JBoss is a collaborative effort between Karim Djaafar
from Sitepilot.fr in France and Sebastian Hennebrueder from laliluna.de in Germany. Karim and
Sebastian cooperate to offer a wide choice of seminars in the English, French and German languages on
their E-Learning platform java-learning.com.

Karim works as a senior consultant for large companies in France and is author of a book focussing on
development with Eclipse and JBoss.

Sebastian works as a consultant and developer and runs the platform laliluna.de which provides a large
number of tutorials about J2EE, Hibernate, Struts and JavaServer Faces.

This part of the series, J2EE development with MyEclipse and JBoss, is written by Sebastian
Hennebrueder and implements the case study explained in the book J2EE Applications with Eclipse and
Jboss
of Karim Djaafar.

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

Table of Content

Table of Figures

FIGURE 1 - SAMPLE J2EE APPLICATION STRUCTURE............................................. 5

FIGURE 2 - SELECT AN EJB PROJECT FORM THE NEW PROJECT DIALOG.......... 7

FIGURE 3 - ADDING THE JBOSS TASK TO THE XDOCLET CONFIGURATION.........8

FIGURE 4 - CREATING A SESSION BEAN WITH MYECLIPSE WIZARDS.................. 9

FIGURE 5 - CLASSES AND INTERFACES AFTER RUNNING XDOCLET.................. 11

FIGURE 6 - MYECLIPSE WIZARD TO CREATE NEW ENTITY BEAN........................ 16

Enterprise Java Bean Development with MyEclipse

3

background image

Web Development with MyEclipse and JBoss – part 2

Tutorial Prerequisites

The reader should be familiar with the basics concepts of J2EE, such as EJB, application server
technologies and how to develop and deploy server side applications.

J2EE Technology Basics

In this section, we briefly introduce the J2EE technologies used throughout this tutorial.

J2EE offers a wide choice of services and containers to develop Web Services, enterprise applications and
web applications. An Enterprise Java Bean (EJB) container is part of J2EE application server specification
and provides features to the developer including distributed communication, threading, scaling, and
transaction management. There are three basic types of EJBs:

Entity Beans

Session Beans

Message Driven Beans.

Entity Bean

The entity bean provides the functionality to map persistent data entities to class objects. An example
entity bean use would be to map a record of a table « dog » to a class object of type « dog ».

Session Bean

The session bean provides functionality to implement business logic. Session beans come in two flavors,
either stateless or stateful. For example, a stateless session bean may be a class which returns only data
when invoked by the client and does not maintain any session state between calls. The stateful session
bean could be used as a shopping cart for an ecommerce site. The cart is stateful, because it saves the
products and other session data between calls in the same session.

Message Driven Beans

Message driven beans allow asynchronous messaging between applications. An internet shop application
can send an order message to a warehouse application.

In our example we will use a session bean to implement the business logic and entity beans to access
entries from the database. The structure of our J2EE application is displayed below in Figure 1.

Enterprise Java Bean Development with MyEclipse

4

background image

Web Development with MyEclipse and JBoss – part 2

Figure 1 - Sample J2EE application structure

MyEclipse and EJB

When developing EJB applications you have to create a number of interfaces and XML description files
with information for the application server. Hand coding theses interfaces and XML files is a tedious task.
MyEclipse offers a number of wizards to create EJBs, while utilizing the powerful XDoclet technology to
create the interfaces and XML files. The developer creates a basic class using the MyEclipse wizard and
the wizard adds XDoclet annotations to the class. These annotations are then interpreted by the XDoclet
processor to create the interfaces and XML files needed for EJB deployment.

Example of XDoclet annotations:

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "itemId"
* @ejb.pk-field
* @return
*/
public abstract String getItemId();

Additional features like EJB project packaging and deployment and debugging makes MyEclipse the
perfect choice to develop EJB applications.

Enterprise Java Bean Development with MyEclipse

5

background image

Web Development with MyEclipse and JBoss – part 2

Design of the EJB Project

In the section below we will explain various aspects of J2EE technology. The design should be understood
as a technology overview introducing technologies like Entity Beans with Container Managed Persistence
(CMP) and design patterns like Data Access Objects (DAO).

As explained earlier in this document, we are using a central Session Bean to implement our business
logic. We will implement two of the use cases introduced in Part One of this three part series:

Login User

Local Dealership Inquiry ( for browsing items which are available in stock)

The Login User use case is implemented as a method in the WebStockAccess Session Bean. This bean will be
responsible for authenticating the user by communicating with the database using a Data Access Object
(DAO) which encapsulates the Java Database Connectivity (JDBC) code. In fact, we do not want to
implement the JDBC query directly in this Session Bean method, but move it to a Data Access Object
(DAO). There are a several advantages to using this design:

First, we have clean separation between our business logic and the underlying JDBC
exceptions and connections.

Second, in the case where we change the underlying database technology, we only
have to check that our DAOs are still working. We do not have to worry about our
business logic.

Third, we can implement database specific DAOs when we want to support multiple
database types.

The Local Dealership Inquiry use case is also implemented as a method in the WebStockAccess Session Bean.
The method returns a list of StockItems which are composite classes that include the information from an
Inventory class and an Item class. We moved the implementation into a DAO object, and the
implementation will use a Finder method of a CMP entity bean.

Enterprise Java Bean Development with MyEclipse

6

background image

Web Development with MyEclipse and JBoss – part 2

Setting up the project

The first step to setting up our project is to create a new EJB project in MyEclipse. This is accomplished by
pressing Ctrl + n and opening the New dialog and then selecting an EJB Project.

Figure 2 - Select an EJB project form the New Project Dialog

An EJB project provides all the features and libraries you need to create a Jar and deploy the project to an
application server.

Open the project properties and select the MyEclipse>XDoclet tab to add a Standard EJB configuration.
We are using the JBoss Application Server, so you have to add a JBoss task to the default tasks shown
below. You can find the needed settings for the JBoss task in Figure 3 below.

Enterprise Java Bean Development with MyEclipse

7

background image

Web Development with MyEclipse and JBoss – part 2

Figure 3 - Adding the JBoss task to the XDoclet configuration.

The data source mapping must be specified according to your database. For MySQL it is mySQL. You can
find all supported mappings in the file jboss-x.y\server\default\conf\standardjbosscmp-jdbc.xml.
Do not forget to create a data source in your JBoss server configuration. We propose jdbc/webstockDS as
JNDI name.

Enterprise Java Bean Development with MyEclipse

8

background image

Web Development with MyEclipse and JBoss – part 2

Use case: Login User

Create a Session Bean in the package com.webstock.ejb. You can find the configuration in Figure 4, below.

Figure 4 - Creating a Session Bean with MyEclipse wizards

Enterprise Java Bean Development with MyEclipse

9

background image

Web Development with MyEclipse and JBoss – part 2

EJB interfaces

In Figure 4 we set Select the access of the EJB to both so that interfaces will be generated by XDcolet for
both local and remote access of the EJB. This setting creates an XDoclet tag @ejb.bean view-type="both"
inside the class file of the EJB. To help you understand why we choose both here, I will give you some
background information about Interfaces.

When you want to use an EJB you do not create an object directly but ask the application server to give
you one. The steps to get a session bean are the following:

Look up a home interface in the Java Naming Directory Interface (JNDI) context.

Call the create method of the home interface

Get an interface to access the EJB

The application server does not let the client access the EJB directly; moreover, the server’s EJB container
will decide whether or not use an EJB from a pool or create one from disk to satisfy the client request. For
client access to the EJB, there are two types of Interfaces: local and remote. Remote interfaces allow an
application to access EJBs on a separate server located on the LAN. These connections are slower because
you have the overhead needed to prepare the data and to transfer it over the LAN. Even on the same
application server the data is prepared for a transfer. Local interfaces allow a faster access to EJBs, but
require that the application run within the same application server JVM. In order to have both interfaces
created we selected both.

DAO interface and class

The DAO interface will be created by XDoclet, but we have to create the class implementing the DAO
interface. You can create a new class, named WebStockAccessDAOImp, in the com.webstock.dao
package. The class should implement the WebStockAccessDAO interface which is not yet created. Just
type it manually in the source code.

Source code snippet:

public class WebStockAccessDAOImp implements WebStockAccessDAO {
}

The next step is to add the loginUser method to our Session Bean. The tag @dao.call specifies that the
method is implemented in a DAO method specified with the name attribute.

/**
* returns the user id if a user is found for username and password
*
* @ejb.interface-method view-type = "remote"
* @dao.call name="loginUser"
* @throws EJBException
* Thrown if method fails due to system-level error.
*/
public String loginUser(String username, String password) throws EJBException {

return null;

}

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

Now, you must specify the DAO class in which the method should be implemented; this is done just
before the class definition in the class file.

@ejb.dao impl-class=" com.webstock.dao.WebStockAccessDAOImp"
*
*/
public class WebStockAccess implements SessionBean {

To create the DAO and the other interfaces of the Session Bean, you must run the XDoclet processor on
the project. This is done by right-clicking on the project and selecting the MyEclipse>Run XDoclet menu
item from the popup menu. Below you can see a picture showing the complete classes and interfaces in
Figure 5. The files we have created so far are marked with a red ellipse.

Figure 5 - Classes and Interfaces after running XDoclet

We have nearly finished this part. Now we need to open the source code of the

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

WebStockAccessDAOImp and implement the init and loginUser methods. You can find the source code
below. We use a data source configured in the JBoss application server. The next paragraph explains how
to create a data source.

public class WebStockAccessDAOImp implements WebStockAccessDAO {

private DataSource dataSource;

public void init() {

InitialContext initialContext = null;
if (dataSource == null)
{

try
{

initialContext = new InitialContext();
dataSource = (DataSource) initialContext

.lookup("java:/jdbc/webstockDS");

} catch (NamingException e)
{

e.printStackTrace();

}

}

}
public String loginUser(String username, String password) throws EJBException {

String userId = null;
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
try
{

connection = dataSource.getConnection();
String sql = "select userid from webstockaccess where username = ? and password = ?

";

ps = connection.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
rs = ps.executeQuery();
if (rs.next())

userId = rs.getString(1);

} catch (SQLException e)
{

// do nothing, we will return null
e.printStackTrace();

} finally
{

try
{

ps.close();
rs.close();
connection.close();

} catch (SQLException e)
{
}

}
return userId;

}

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

The init method is called by default after having created the DAO. Have a look in the
WebStockAccessSession class to see what XDoclet created for you and how the DAO is accessed.

So far we have configured our EJB project, created a DAO interface, configured our Session Bean
WebStockAccess to use the DAO and created a dummy method loginUser in the Session Bean. We have also
implemented the loginUser and init methods in the DAO. XDoclet created all we needed to initialize the
DAO and to delegate the method calls. We can now test what we and XDoclet have created.

Creating a Data source

Copy the driver of your database to \jboss-x.y\server\default\lib and then create the database before
configuring the data source. You can find configuration examples for data sources for all supported
databases in \jboss-x.y\docs\examples\jca\. Create a new data source file named your-dbds.xml and
copy it to the directory \jboss-x.y\server\default\deploy. JBoss will read the file and output a message
in the log or in the console showing that the data source is created successfully.

Below you can see an example data source file for a MySQL database:

<datasources>
<local-tx-datasource>
<jndi-name>jdbc/webstockDS</jndi-name>
<connection-url>jdbc:mysql://localhost:3306/test</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>r</password>
<exception-sorter-class-
name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-
class-name>
<metadata>
<type-mapping>mySQL</type-mapping>
</metadata>
</local-tx-datasource>
</datasources>

Deployment and Testing

To test our application we need to create the table needed by our use case. Create the table
webstockaccess (see Resources at the end of this document).

Add a user entry in your table:

insert into webstockaccess (userid, username, password) values ('1', 'Hugo','h');

Deploy the EJB Project to the application server and verify that it is successfully deployed.

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

Creating a J2EE test client

In order to test our EJBs we need an EJB test client. First we must create a new Java project. Next, we
create a class named TestClient in the com.webstock package and implement the following simple test
method. The testUserLogin() method calls the session bean method we have implemented, and uses an
existing user (Hugo) with the correct password. The testUserLogin() method also uses a non existing user
for testing purposes. The TestClient creates an initial JNDI that will allow our application to get access to
resources like home interfaces or data sources from a JNDI.

Our test method testUserLogin() uses the JNDI to get a home interface of our WebStockAccess session
bean. It cannot convert it directly to a local interface but needs the method PortableRemoteObject to
narrow the object. The reason is as explained before that a remote home interface is not accessed directly.
Each request is packed to be sent over a LAN, unpacked at the target server and the result is returned the
same way.

As our client does not execute within the application server, we need access to the remote interface to
access our EJBs.

package com.webstock;

import java.rmi.RemoteException;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import javax.ejb.CreateException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;

import com.webstock.interfaces.WebStockAccess;
import com.webstock.interfaces.WebStockAccessHome;

public class TestClient {

private InitialContext initialContext;

/**
* @param args
*/
public static void main(String[] args) {

TestClient client = new TestClient();
client.init();
client.testUserLogin();

}

public void init() {

Properties properties = new Properties();
properties = new Properties();
properties.put("java.naming.factory.initial",

"org.jnp.interfaces.NamingContextFactory");

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

properties.put("java.naming.factory.url.pkgs",

"org.jboss.naming:org.jnp.interfaces");

properties.put("java.naming.provider.url", "jnp://localhost:1099");
properties.put("jnp.disableDiscovery", "true");

try
{

InitialContext context = new InitialContext(properties);

} catch (NamingException e)
{

e.printStackTrace();

}

}

private void testUserLogin() {

try
{

Object object = initialContext.lookup(WebStockAccessHome.JNDI_NAME);
WebStockAccessHome webStockAccessHome = (WebStockAccessHome) PortableRemoteObject

.narrow(object, WebStockAccessHome.class);

WebStockAccess webStockAccess = webStockAccessHome.create();
System.out.println(webStockAccess.loginUser("Hugo", "h"));
System.out.println("Bad user: "

+ webStockAccess.loginUser("baduser", "b"));

} catch (RemoteException e)
{

e.printStackTrace();

} catch (NamingException e)
{

e.printStackTrace();

} catch (CreateException e)
{

e.printStackTrace();

}

}

We have finished implementing the first use case. We needed to prepare the structure we chose, so the
first use case took considerable efforts. However, the second use case can reuse this structure.

Use case: Local Dealership Inquiry

The second use case permits us to browse items available in the stock. To access the stock we will need the
CMP entity bean, Inventory. To read detail information about our item, we will need another CMP entity
bean, Item. Later we will implement our business logic using both CMP entity beans.

CMP and Finder methods

Why do we use CMP entity beans?

There are two types of entity beans:

Container Managed Persistence beans (CMP)

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

Bean Managed Persistence beans (BMP)

CMP entity beans only have abstract getter and setter method and a description file which defines which
getter belongs to which database fields. All SQL queries to the database are generated by the application
server’s EJB container. BMP entity beans do not provide this functionality; moreover, with BMP entity
beans you have to code all queries on your own.

In the first versions of CMP the query language for finder methods was very basic and the features of
CMP very limited. EJB 2.4 is quite powerful and there is no need to create BMP implementations for
simple entity beans any more.

Now, we continue our project by creating a new entity Bean using the MyEclipse wizard. We will
implement a limited choice of the attributes shown in the model in Part One of this series. You may
complete the implementation on your own.

Figure 6 - MyEclipse wizard to create new entity bean

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

The next task is to provide the abstract getters and setters for our attributes. Each of these abstract
methods is described with annotations, which are used by XDoclet to create the needed interfaces.

Example of annotations for a primary key field:

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "itemId"
* @ejb.pk-field
* @return
*/

The annotations noted above tell XDoclet to create remote and local interfaces for the method. It further
defines the table column to which the getter is mapped to and it defines the column as a primary key. For

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

further information about XDoclet you can have a look in the XDoclet reference provided by MyEclipse in
the Help pages.

Add the following methods and annotations to your class:

public abstract class Inventory implements EntityBean {

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "itemId"
* @ejb.pk-field
* @return
*/
public abstract String getItemId();

/**
* @ejb.interface-method view-type = "both"
* @param itemId
*/
public abstract void setItemId(String itemId);

/**
* @ejb.interface-method view-type = "both"
*
* @return
*/
public abstract InventoryData getData();

/**
* @ejb.interface-method view-type = "both"
*
* @param name
*/
public abstract void setData(InventoryData inventoryData);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "partId"
* @return
*/
public abstract String getPartId();

/**
* @ejb.interface-method view-type = "both"
* @param partId
*/
public abstract void setPartId(String partId);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "quantity"
* @return
*/
public abstract int getQuantity();

/**
* @ejb.interface-method view-type = "both"

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

* @param quantity
*/
public abstract void setQuantity(int quantity);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "shelf"
* @return
*/
public abstract String getShelf();

/**
* @ejb.interface-method view-type = "both"
* @param shelf
*/
public abstract void setShelf(String shelf);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "location"
* @return
*/
public abstract String getLocation();

/**
* @ejb.interface-method view-type = "both"
* @param location
*/
public abstract void setLocation(String location);

/**
* @ejb.create-method
*/
public String ejbCreate(InventoryData inventoryData) throws CreateException {

setItemId(inventoryData.getItemId());
this.setData(inventoryData);
return null;

}
public void ejbPostCreate(InventoryData inventoryData) throws CreateException {
}

Our use case allows us to browse all stocked items in the WebStock inventory system. To accomplish this
we need to query all inventory records which have a quantity which is not zero. We will implement a
custom finder. A finder is a database-independent query implemented in the EJB-QL language that
allows the querying of data sources like SQL. The application server translates it to the database- specific
SQL language based on the database you selected in the earlier data source mapping.

Below you can find the annotation needed for your finder:

* @ejb.finder
* query="select object (i) from Inventory as i where i.quantity <> 0"
* signature="java.util.Collection findStockedItems()"
* description="find all stock items with positive quantity"
*/
public abstract class Inventory implements EntityBean {

Enterprise Java Bean Development with MyEclipse

1

background image

Web Development with MyEclipse and JBoss – part 2

The last step is to complete the annotations of your class. We will add convenience annotations to have
the tables created automatically:

* @ejb.bean name="Inventory"
* display-name="Name for Inventory"
* description="Description for Inventory"
* jndi-name="ejb/Inventory"
* type="CMP"
* cmp-version="2.x"
* view-type="local"
* primkey-field="itemId"
* @jboss.persistence
* create-table="true"
* remove-table="false"
* table-name="inventory"

We have finished our Inventory method. We can now run XDoclet to have all the interfaces created and
proceed to the second entity bean that we need: Item.

You are a CMP expert by now, so I will not give you any details but only the source which needed to be
implemented. Create a second entity bean named Item, implement it and run XDoclet when finished.

Source code for the entity bean, Item:

* @ejb.bean name="Item"
* display-name="Name for Item"
* description="Description for Item"
* jndi-name="ejb/Item"
* type="CMP"
* cmp-version="2.x"
* view-type="local"
* primkey-field="partId"
* @jboss.persistence
* create-table="true"
* remove-table="false"
* table-name="item"
*/
public abstract class Item implements EntityBean {

/** The entity context */
private EntityContext context;

public Item() {

super();
// TODO Auto-generated constructor stub

}

/**
* @ejb.interface-method view-type = "both"
*
* @return
*/
public abstract ItemData getData();

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

/**
* @ejb.interface-method view-type = "both"
*
* @param name
*/
public abstract void setData(ItemData itemValue);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "partid"
* @ejb.pk-field
* @return
*/
public abstract String getPartId();

/**
* @ejb.interface-method view-type = "both"
* @param partid
*/
public abstract void setPartId(String partid);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "description"
* @return
*/
public abstract String getDescription();

/**
* @ejb.interface-method view-type = "both"
* @param description
*/
public abstract void setDescription(String description);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "weight"
* @return
*/
public abstract Float getWeight();

/**
* @ejb.interface-method view-type = "both"
* @param weight
*/
public abstract void setWeight(Float weight);

/**
* @ejb.interface-method view-type = "both"
* @ejb.persistence column-name = "image_url"
* @return
*/
public abstract String getImageUrl();

/**
* @ejb.interface-method view-type = "both"
* @param image_url
*/
public abstract void setImageUrl(String image_url);

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

/**
* @ejb.create-method
*/
public String ejbCreate(ItemData itemData) throws CreateException {

setPartId(itemData.getPartId());
setData( itemData);
return null;

}

public void ejbPostCreate(ItemData itemData) throws CreateException {
}

Implementing the business methods

In this part we are going to implement the business logic using the two entity beans that we have just
created. Open the class WebStockAccess and add a method getItemsInStock. This method will be
moved to our DAO. This must be configured using the annotations. Have a look at the source code
below:

/**
* returns a list of Items
* @ejb.interface-method view-type="both"
* @dao.call name="getItemsInStock"
* @return
* @throws EJBException
*/
public List getItemsInStock() throws EJBException{

return null;

}

Run XDoclet to have the new method added to our interface WebStockDAO and open the file
WebStockAccessDAOImp. This file should show a Java error as you configured it to implement the
WebStockAccessDAO interface but you have not implemented the getItemsInStock method yet. This is
our next task.

We want to use the finder to select the items with a positive quantity and show the detail data of each
item. To do this we are going to return a list of objects showing attributes from two entity beans:
Inventory and Item. In order to provide the information from two objects in one object, we will use
composition.

There are two possibilities to have attributes from two classes. First, we could use inheritance from both
classes. However, Java does not support multiple-inheritance. The second technique is to use
composition. Even if you only need attributes from one class, composition is often the better choice as it
allows you to select attributes from the available child classes and control attribute access through
business logic.

Create a class StockItem and add the classes ItemData and InventoryData as private attributes.

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

public class StockItem implements Serializable {

private ItemData itemData;
private InventoryData inventoryData;

public StockItem(){

itemData = new ItemData();
inventoryData = new InventoryData();

}

Implement delegate methods for each attribute of ItemData and StockItem. Below you can see an
example of a delegate method for the attribute ItemId. Eclipse provides a convenient way to create
delegate methods. In the context menu of the source code, choose Source and then Generate delegate
methods
.

public String getItemId() {

return inventoryData.getItemId();

}

public void setItemId(String itemId) {

inventoryData.setItemId(itemId);

}

Now we are ready to implement our business method. Open the file WebStockAccessDAOImp and add
the method getItemsInStock as shown below. The method uses the finder to look up all stocked items
with positive quantities. It loops over the list of found inventory entries, looks up the detail data for each
inventory item and creates a StockItem. The StockItem is added to a List which is returned as the result.

/**

* returns a List of StockItems, which are constructed from a List selected by a

finder and

* detail data from an Entity CMP
*
*/
public List getItemsInStock() throws EJBException {

List items = new ArrayList();
ItemLocalHome itemHome;
InventoryLocalHome inventoryHome;
try
{

InitialContext initialContext = new InitialContext();
itemHome = (ItemLocalHome) initialContext.lookup(ItemLocalHome.JNDI_NAME);
inventoryHome = (InventoryLocalHome) initialContext

.lookup(InventoryLocalHome.JNDI_NAME);

} catch (NamingException e1)
{

e1.printStackTrace();
throw new EJBException("Could not access items");

}

try
{

Collection inventoryItems = inventoryHome.findStockedItems();
for (Iterator iter = inventoryItems.iterator(); iter.hasNext();)
{

InventoryLocal element = (InventoryLocal) iter.next();
try

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

{

ItemLocal item = itemHome.findByPrimaryKey(element.getPartId());
StockItem stockItem = new StockItem();
stockItem.setQuantity(element.getQuantity());
stockItem.setPartId(item.getPartId());
stockItem.setDescription(item.getDescription());
stockItem.setImageUrl(item.getImageUrl());
stockItem.setWeight(item.getWeight());
stockItem.setLocation(element.getLocation());
items.add(stockItem);

} catch (FinderException e)
{

e.printStackTrace();
throw new EJBException("Corrupt data in stock");

}

}

} catch (FinderException e)
{

e.printStackTrace();

}
return items;

}

To give you a short summary, we have implemented a composite class to hold information from two
other classes. We created CMP entity beans and a custom finder methods using EJB-QL. Finally, we
added a second business method to our session bean which is delegated to a DAO class.

Deployment and Testing

Deploy your application to the JBoss application server and verify that it is successfully deployed. Verify
in your database that the item and inventory tables were created. The creation of these tables was
configured using XDoclet tags in the definition of the CMP entity beans.

Our application looks for entries with positive quantity in the inventory table. If entries are found with
positive quantities, the details of each entry are retrieved from the item table. Next we need to create
some example data with the following insert statements:

insert into inventory ( partid , itemid , quantity , shelf , "location") values
('p2','i2',5,'top','B66');
insert into inventory ( partid , itemid , quantity , shelf , "location") values
('p3','i3',3,'middle','B66');
insert into item ( partid, description , weight , image_url) values
('p2', 'hard disk type xy', 500, 'no image');
insert into item ( partid, description , weight , image_url) values
('p3', 'monitor lcd 17-5311', 3500, 'no image');

Creating a J2EE Test client

Open the TestClient class and add the following method to test your implementation of the Local
Dealership Inquiry use case:

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

private void testGetStockItems() {

try
{

Object object = initialContext.lookup(WebStockAccessHome.JNDI_NAME);
WebStockAccessHome webStockAccessHome = (WebStockAccessHome) PortableRemoteObject

.narrow(object, WebStockAccessHome.class);

WebStockAccess webStockAccess = webStockAccessHome.create();
List items = webStockAccess.getItemsInStock();
for (Iterator iter = items.iterator(); iter.hasNext();)
{

StockItem element = (StockItem) iter.next();
System.out.println(element.toString());

}

} catch (RemoteException e)
{

e.printStackTrace();

} catch (NamingException e)
{

e.printStackTrace();

} catch (CreateException e)
{

e.printStackTrace();

}

}

Add a call to this method in your main method and execute it. If your implementation is correct, your
output should resemble the following:

{partId=p2 description=hard disk type xy weight=500.0 imageUrl=no image}
{partId=p3 description=monitor lcd 17-5311 weight=3500.0 imageUrl=no image}

Use case: Add Stock Item

In this use case we will provide a method needed to create an item in the stock. We will not delegate the
method to the DAO class, but implement it directly in the Session Bean. The reason is that we are using
only EJB access and not native SQL in this method.

Our method takes a stockItem as a parameter, reads the item and the inventory information from it,
generates a primary key, and then saves both objects in the database.

/**
* @ejb.interface-method view-type="both"
* @param stockItem
* @return
* @throws EJBException
*/
public StockItem addItem(StockItem stockItem) throws EJBException{

//extract composited data
ItemData itemData = stockItem.getItemData();
InventoryData inventoryData = stockItem.getInventoryData();
// we are not having a defined part number so we will just create a random number
String partId = ItemUtil.generateGUID(this.getClass());
itemData.setPartId(partId);

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

inventoryData.setPartId(partId);
String itemId = InventoryUtil.generateGUID(this.getClass());
inventoryData.setItemId(itemId);
// get Home interfaces
try
{

InitialContext context = new InitialContext();
ItemLocalHome itemLocalHome = (ItemLocalHome)

context.lookup(ItemLocalHome.JNDI_NAME);

InventoryLocalHome ilh = (InventoryLocalHome)

context.lookup(InventoryLocalHome.JNDI_NAME);

ItemLocal itemLocal = itemLocalHome.create(itemData);
InventoryLocal inventoryLocal = ilh.create(inventoryData);
stockItem.setInventoryData(inventoryData);
stockItem.setItemData(itemData);

} catch (NamingException e)
{

// lazy handling of exception, do not do this in real world applications.
e.printStackTrace();

} catch (CreateException e)
{

// TODO Auto-generated catch block
e.printStackTrace();

}

return stockItem;

}

Modifying the J2EE Test client

To test the method, open the TestClient that you created before and add the following method.

public void testAddStockItem(){

try
{

Object object = initialContext.lookup(WebStockAccessHome.JNDI_NAME);
WebStockAccessHome webStockAccessHome = (WebStockAccessHome) PortableRemoteObject

.narrow(object, WebStockAccessHome.class);

WebStockAccess webStockAccess = webStockAccessHome.create();
StockItem stockItem = new StockItem();
stockItem.setWeight(20f);
stockItem.setQuantity(5);
stockItem.setDescription("test");
webStockAccess.addItem(stockItem);

} catch (ClassCastException e)
{

// TODO Auto-generated catch block
e.printStackTrace();

} catch (RemoteException e)
{

// TODO Auto-generated catch block
e.printStackTrace();

} catch (NamingException e)
{

// TODO Auto-generated catch block
e.printStackTrace();

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

} catch (CreateException e)
{

// TODO Auto-generated catch block
e.printStackTrace();

}

}

Congratulations, you have finished the second part of this series and implemented all the business
methods that are needed for the web application construction. The web application will be constructed in
the last part of this series.

Conclusion and Outlook

In this second part of our three part series we introduced a variety of technologies and design strategies
that illustrated how to implement a concrete case study using J2EE technology. We tried to show a
number of techniques in a small example application, while the implementation became more and more
“sophisticated”.

The WebStock case study could be extended by a number of exciting technologies:

Usage of Message Driven Beans to implement asynchronous messaging between local

and central warehouses.

Authentication using LDAP directories and implementation of JAAS authorization to

configure the access of roles to business logic.

Complex CMP relationships between entity beans.

Usage of the powerful design pattern Value Objects which is well supported by XDoclet.

This full case study is used in seminars held on the E-Learning platform java-learning.com. The seminars
are held for JBoss and WebSphere application servers in the English, German and French languages.

Enterprise Java Bean Development with MyEclipse

2

background image

Web Development with MyEclipse and JBoss – part 2

Resources

Description

Name

Size

Download method

Source code and script
for the WebStock
application

WebStockModule2.zip

FTP

Enterprise Java Bean Development with MyEclipse

2


Wyszukiwarka

Podobne podstrony:
PRACTICAL SPEAKING EXERCISES with using different grammar tenses and constructions, part Ix
WROX C# Web Services Building Web Services with ASP NET and NET Remoting
Create Your Own Search Engine with PHP and Google Web Services
Developing Usability Tools And Techniques For Designing And Testing Web Sites
Correctexams Microsoft 70 315 Mcsd Mcad Develop & Implement Web Apps With C Sharp Edt6
Farina Reproduction of auditorium spatial impression with binaural and stereophonic sound systems
11 3 2 3 Lab Testing Network Latency with Ping and Traceroute
lecture 17 Sensors and Metrology part 1
ARRL QST Magazine Clean up Signals with Band Pass Filters (part 1) (1998) WW
SHSBC 247 R2 12 THEORY AND PRACTICE PART I
Ship Power Systems and Design Part 3
Business Process Modeling with EPC and UML
OReilly Programming Web Services with SOAP, OReilly Programming Web Services with SOAP
Cho Chikun's encyclopedia of life and death part three a
Cho Chikun's encyclopedia of life and death part one ele
Building web applications with flask
M Kaufmann Programming Cameras and Pan tilts With DirectX and Java fly (2)
Applying Principles of Neurodevelopment to Clinical Work with Maltreated and Traumatized Children
9 G2 H2 DONOR RECRUITMENT AND MOTIVATION part 2 po korekcie MŁL

więcej podobnych podstron