Migration Lab - Part III
Turn WBOnline into a Best Practice J2EE 1.3 Application

OBJECTIVES

This workshop will show you the process of developing a J2EE application using WebSphere Studio Application Developer 5.0. The WBOnline Banking Application will be used to demonstrate the development process. This workshop is divided into three parts:

The WBOnline Application was built based on the J2EE 1.2 Specification. In order to bring this application to the J2EE 1.3 Specification, we will use WebSphere Studio Appliation Developer to rebuild our EJBs. In this workshop, you will learn:

Please complete Part I & II of this workshop before proceeding.

Note:  This workshop requires that the following products are installed:
  • WebSphere Studio Application Developer 5.0
  • DB2 UDB 7.2 FP7

Section 1 - Setup for Migration

___ 1. Delete WBOnlineEAR and WBOnlineEJB Projects

Note: We are deleting these projects and recreate the EAR and EJB projects so you can gain experience in working with the J2EE 1.3 tools.  Migration usually doesn't include deleting projects!  Version 5.0 EA will have migration tools to migrate an existing J2EE 1.2 project to a J2EE 1.3 project).


a. If not already started, start WebSphere Studio Application Developer.

b. From the Navigator View, while holding down the CTRL key, click to select WBOnlineEAR and WBOnlineEJB projects.

c. Click mouse button 2 on the selected projects and choose Delete... from the popup menu.

d. From the Delete selected project(s) dialog, click OK .

e. From the Confirm Multiple Project Delete dialog, choose Also delete contents in the file system and click Yes .

f. If a Repair Server Configuration dialog appears, make sure all items are checked and click the OK button.

___ 2. Create a new J2EE 1.3 WBOnline EAR

a.Choose File->New->Project... from the menu bar.

b. From the New Project dialog, choose J2EE from the lefthand pane and choose Enterprise Application Project on the righthand pane. Click Next>.

c. From the Enterprise Application Project Creation - J2EE Specification version dialog, choose Create J2EE 1.3 Enterprise Application project and click Next>.

d. From the Enterprise Application Project Creation - Enterprise Application Project dialog, specify the following:

Parameter Value
Enterprise application project name WBOnlineEAR
Application client module unchecked
EJB project name WBOnlineEJB
Web project name WBOnline

Click the Finish button.

Section 2 - Migrating WBOnline Web Module

___ 1. Convert WBOnline Web Module from J2EE 1.2 to J2EE 1.3

a. From the J2EE Navigator View, select WBOnline Project.

b. Click mouse button 2, and choose Properties from the pop-up menu.

c. From the Properties for WBOnline dialog, choose Web from the left-hand list.

d. Change the J2EE Level from 1.2 to 1.3.

e. Click Apply.

f. Click the OK button.

The WBOnline Project will look like the following in the Navigator View:

The WBOnline Web Project has some errors at this point because the EJBs have not been created yet.

Section 3 - Create new WBOnline EJBs

___ 1. Creating EJB 2.0 using Bottom up Approach

a. From the J2EE Hierarchy View of the J2EE Perspective, expand EJB Modules and select WBOnlineEJB.


b. Click mouse button 2 and select Generate->EJB to RDB Mapping... from the popup menu.

c. From the EJB to RDB Mapping dialog, click Next> .

d. From the EJB to RDB Mapping - Create new EJB/RDB Mapping dialog, verify that the Bottom Up Approach is selected and then click Next>.



e. From the Database Connection dialog, specify the following:

Parameter Value
Connection name AIS
Database AIS
Database vendor type DB2 UDB V7.2
JDBC driver IBM DB2 APP DRIVER
Class location x:\SQLLIB\java\db2java.zip


And then click Next>.

f. From the Selective Database Import dialog, click the Customer, Account, and Txn tables.


And then click Next>.

g. From the Create new EJB/RDB Mapping dialog, specify the following:

Parameter Value
Select a specification level Generate 2.0 enterprise beans
Package for generated EJB classes ejbs


And then click Finish. In a moment, the mapping will be created and it will be displayed in the mapping editor. Take a moment to look at the mapping if you like. Then, close the mapping editor.

Note: If you see 2 warnings in the task sheet indicating the number of attributes and columns don't match, you should close the mapping editor, close the J2EE perspective and stop and start Application Developer.  This is a workaround to a problem in the current driver of Application Developer we are using.  The errors may not disappear from the task sheet immediately.

___ 2. Examine the EJB Relationship

a. From the J2EE Hierarchy View of the J2EE Perspective, double click on WBOnlineEJB. The Overview Page of the EJB Deployment Descriptor is displayed.

b. Scroll down to the Relationships 2.0 section:


Select the Account_To_Customer and click Edit... .

c. From the Edit Relationship dialog, click Next> .

d. From the Relationship Roles dialog, you can see the relationship between Custsomer and Account. A Customer can have one to many Accounts. Pay special attention to the CMR fields. They are used later on when we define additional finder methods. Since we haven't change anything here, click Cancel when you finish examining the relationship.

e. Repeat steps b-d for the Txn_To_Account Relationship if you like.

___ 3. Specify the Datasource Used

a. With the Overview Page of EJB Deployment Descriptor still opened, scroll down to the WebSphere Bindings section.

b. Add the JNDI name of the AIS datasource, jdbc/AIS , in the JNDI - CMP Factory Connection Binding column.

Hit Ctrl+S to save the changes and close the Deployment Descriptor Editor.

___ 4. Add Methods into the Account EJB

We will add a field and some methods to the AccountBean class.

a. From the J2EE Hierarchy View of the J2EE Perspective, expand EJB Modules->WBOnlineEJB->Account and double click on AccountBean .

b. Add the following field and methods:  (Note: you should use cut and paste)  (Note: This code dealing with total balances is used internally during a live demonstration of WBOnline.  It really isn't important for this workshop.  This code will be more relevent when we have Hot-Method Replace).

	private float totalBalance;

/**
* Returns the totalBalance.
* @return float
*/
public float getTotalBalance() {
return totalBalance;
}

/**
* Sets the totalBalance.
* @param totalBalance The totalBalance to set
*/
public void setTotalBalance(float totalBalance) {
this.totalBalance = totalBalance;
}

private float addAccountBalances() {
return 1;
}

public void calculateTotalBalance() {

totalBalance = addAccountBalances();
// totalBalance=-999999; //TEST DATA
}

c. Add calculateTotalBalance(); to the ejbActivate() method so that the ejbActivate method looks like this:

	public void ejbActivate() {
calculateTotalBalance();
}

d. Hit Ctrl-S to save.

___ 5. Promote Methods to the Local Interface

a. While still editing AccountBean.java, multiple select getTotalBalance() and setTotalBalance(float) from the Outline View (Note: By default, this is in the lower left hand corner of the workbench)

b. Click mouse button 2 and choose Enterprise Bean->Promote to Local Interface. Those two methods are then added to the AccountLocal.java.

___ 6. Add Methods into the Txn EJB

We will add a field and some methods to the TxnBean class.

a. From the J2EE Hierarchy View of the J2EE Perspective, expand EJB Modules->WBOnlineEJB->Txn and double click on TxnBean .

b. Add the following field and methods:  ( Note: you should use cut and paste)  (Note: This code dealing with total balances is used internally during a live demonstration of WBOnline.  It really isn't important for this workshop.  This code will be more relevent when we have Hot-Method Replace).)

	private float totalBalance;
/**
* Returns the totalBalance.
* @return float
*/
public float getTotalBalance() {
return totalBalance;
}

/**
* Sets the totalBalance.
* @param totalBalance The totalBalance to set
*/
public void setTotalBalance(float totalBalance) {
this.totalBalance = totalBalance;
}

private float addTxnBalances() {
return 1;
}

public void calculateTotalBalance() {

totalBalance = addTxnBalances();
// totalBalance=-999999; //TEST DATA
}

c. Add calculateTotalBalance(); to the ejbActivate() method so that the ejbActivate method looks like this:

	public void ejbActivate() {
calculateTotalBalance();
}

d. Hit Ctrl-S to save.

___ 7. Promote Methods to the Local Interface

a. While still editing TxnBean.java, multiple select getTotalBalance() and setTotalBalance(float) from the Outline View (it is usually located at the bottom left of the workspace).

b. Click mouse button 2 and choose Enterprise Bean->Promote to Local Interface. Those two methods are then added to the TxnLocal.java

___ 8. Create AccountActivity Session Beans

One of the feature in EJB 2.0 is the capability of defining both local and remote client interface. This local programming model provides lighter weight access to a component than the remote one. We will create an AccountActivity Session Bean to access a list of accounts owned by a customer. This will use the local interfaces of our Entity EJBs.

a.Choose File->New->Enterprise Bean from the menu bar.

b. From the Enterprise Bean Creation dialog, choose EJB Project : WBOnlineEJB.

c. Click Next>.

d. From the Create a 2.0 Enterprise Bean dialog, select Session bean and specify the following:

Parameter Value
EJB project WBOnlineEJB
Bean name AccountActivity
Source folder ejbModule
Default package ejbs

e. Click Next>.

f. From the Enterprise Bean Details dialog, specify the following:

Parameter Value
Session type Stateless
Local client view unchecked
Remote client view checked

g. Click the Finish button.

___ 9. Add Methods into the AccountActivity EJB

a. From the J2EE Hierarchy View of the J2EE Perspective, expand EJB Modules->WBOnlineEJB->AccountActivity and double click on AccountActivityBean.

b. We will be adding the following to the AccountActivityBean:

customerHome a field to hold a CustomerHome Object
getCustomerHome() a method to lookup the CustomerHome
getAccountDataForCustomer(int input_cust_num) return an AccountListData databean - a list of accounts owned by a customer

Append the following code to AccountActivityBean :  (Note: you should use cut and paste)

private CustomerLocalHome customerHome;

private CustomerLocalHome getCustomerHome() throws RemoteException {
try {
InitialContext initCtx = new InitialContext();
Object objref = initCtx.lookup("java:comp/env/ejb/Customer");
return (CustomerLocalHome) objref;
} catch (NamingException ne) {
ne.printStackTrace();
throw new RemoteException(
"Error looking up CustomerHome object: " + ne.getMessage());
}
}

public databeans.AccountListData getAccountDataForCustomer(
int input_cust_num) {
databeans.AccountListData alist = new databeans.AccountListData();
try {
customerHome = getCustomerHome();
CustomerLocal customerLocal =
customerHome.findByPrimaryKey(
new CustomerKey(new Integer(input_cust_num)));
Collection col = customerLocal.getAccount();
Iterator it = col.iterator();
Vector v = new Vector();
while (it.hasNext()) {
AccountLocal accountLocal =
(AccountLocal) javax.rmi.PortableRemoteObject.narrow(
it.next(),
AccountLocal.class);
AccountKey key = (AccountKey) accountLocal.getPrimaryKey();
databeans.AccountData ad = new databeans.AccountData();
ad.setAcct_num(key.getAcct_number().intValue());
ad.setBalance(accountLocal.getBalance());
if (accountLocal.getTotalBalance() == 1)
alist.setCalculateRealBalance(true);
else
alist.setCalculateRealBalance(false);
v.addElement(ad);
}
alist.setAccountList(new databeans.AccountData[v.size()]);
for (int i = 0; i < alist.getAccountList().length; i++) {
alist.setAccountList(i, (databeans.AccountData) v.elementAt(i));
}
alist.calculateTotalBalance();
alist.setInput_cust_num(input_cust_num);
} catch (java.rmi.RemoteException re) {
System.err.println("Problem getting Customer Local object");
re.printStackTrace();
} catch (javax.ejb.FinderException fe) {
System.err.println("Problem finding Customer EJB");
fe.printStackTrace();
}
return alist;
}

c. Add the following import statements:

import java.util.*;
import java.rmi.RemoteException;
import javax.ejb.FinderException;
import javax.naming.InitialContext;
import javax.naming.NamingException;

d. Hit Ctrl-S to save. (The compile errors will be fixed in future steps.)

___ 10. Promote getAccountDataForCustomer() method to the Remote Interface

a. While still editing AccountActivityBean.java, select getAccountDataForCustomer(int) from the Outline View (it is usually located at the bottom left of the workspace).

b. Click mouse button 2 and choose Enterprise Bean->Promote to Remote Interface. A new method is added to the AccountActivity.java.

___ 11. Move the Databean Classes to a Utility Jar

The databeans.AccountListData class and other databeans classes were packaged in the WBOnline Web project. ( Note: These are light weight java classes which are used to represent the data returned from a set of EJB entities)  Since WBOnline Web project depends on the WBOnlineEJB EJB project, and if we need to reference the databeans from the EJB project, we will create a circular dependency problem. The best practice here is to move the databeans into a utility jar in the EAR.

a. To create a new java project, choose File->New->Project... from the menu bar.

b. From the New Project dialog, choose Java from the lefthand pane and choose Java Project on the righthand pane. Click Next>

c. Specify a Project name of WBOnlineUtility and click Finish.

d. From the J2EE Navigator View of the J2EE Perspective, expand WBOnline->Java Source and click mouse button 2 on the databeans package and then choose Move... .

e. From the Move dialog, select WBOnlineUtility and click OK.

___ 12. Add the Utility Jar to WBOnlineEAR

a. From the J2EE Hierarchy View, expand Enterprise Applications and double click on WBOnlineEAR .

b. From the Application Deployment Descriptor Editor, select the Module tab and click the Add... button under the Project Utility JARs section.

c. From the Add Utility JAR dialog, select the WBOnlineUtility Project and click Finish.

d. Hit CTRL-S to save.

e. Close the Application Deployment Descriptor Editor.

___ 13. Add the Utility Jar to WBOnlineEJB Project Properties

a. From the J2EE Hierarchy View, expand EJB Modules and click mouse button 2 on WBOnlineEJB and choose Properties.

b. From the Properties for WBOnlineEJB dialog, select Java JAR Dependencies on the lefthand pane and check WBOnlineUtility.jar.

c. Click Apply to apply the changes. WBOnlineUtility will also be added to the Java Build Path.

d. Click OK.

___ 14. Create TxnActivity Session Bean

We will be creating the TxnActivity Session Bean similar to AccountActivity Session Bean.

a.Choose File->New->Enterprise Bean from the menu bar.

b. From the Enterprise Bean Creation dialog, choose EJB Project : WBOnlineEJB.

c. Click Next>.

d. From the Create a 2.0 Enterprise Bean dialog, select Session bean and specify the following:

Parameter Value
EJB project WBOnlineEJB
Bean name TxnActivity
Source folder ejbModule
Default package ejbs

e. Click Next>.

f. From the Enterprise Bean Details dialog, specify the following:

Parameter Value
Session type Stateless
Local client view unchecked
Remote client view checked

g. Click the Finish button.

___ 15. Add Methods into the TxnActivity EJB

a. From the J2EE Hierarchy View of the J2EE Perspective, expand EJB Modules->WBOnlineEJB->TxnActivity and double click on TxnActivityBean.

b. We will be adding the following to the AccountActivityBean:

accountHome a field to hold a AccountHome Object
getAccountHome() a method to lookup the AccountHome
getTxnDataForAccount(int input_acct_num) return an TxnListData databean - a list of txn in an account

Append the following code to TxnActivityBean :

private AccountLocalHome accountHome;

private AccountLocalHome getAccountHome() throws RemoteException {
try {
InitialContext initCtx = new InitialContext();
Object objref = initCtx.lookup("java:comp/env/ejb/Account");
return (AccountLocalHome) objref;
} catch (NamingException ne) {
ne.printStackTrace();
throw new RemoteException(
"Error looking up AccountHome object: " + ne.getMessage());
}
}

public databeans.TxnListData getTxnDataForAccount(int input_acct_num) {
databeans.TxnListData tlist = new databeans.TxnListData();
try {
accountHome = getAccountHome();
AccountLocal accountLocal =
accountHome.findByPrimaryKey(
new AccountKey(new Integer(input_acct_num)));
Collection col = accountLocal.getTxn();
Iterator it = col.iterator();
Vector v = new Vector();
while (it.hasNext()) {
TxnLocal txnLocal =
(TxnLocal) javax.rmi.PortableRemoteObject.narrow(
it.next(),
TxnLocal.class);
TxnKey key = (TxnKey) txnLocal.getPrimaryKey();
databeans.TxnData td = new databeans.TxnData();
td.setTxn_num(key.getTxn_number().intValue());
td.setTxn_amount(txnLocal.getAmount());
td.setTxn_date(txnLocal.getTxn_date());
td.setTxn_type(txnLocal.getTxn_type());
if (txnLocal.getTotalBalance() == 1)
tlist.setCalculateRealBalance(true);
else
tlist.setCalculateRealBalance(false);
v.addElement(td);
}
tlist.setTxnList((new databeans.TxnData[v.size()]));
for (int i = 0; i < tlist.getTxnList().length; i++) {
tlist.setTxnList(i, (databeans.TxnData) v.elementAt(i));
}
tlist.calculateTotalBalance();
tlist.setInput_acct_num(input_acct_num);

} catch (java.rmi.RemoteException re) {
System.err.println("Problem getting Account Local object");
re.printStackTrace();
} catch (javax.ejb.FinderException fe) {
System.err.println("Problem finding Account EJB");
fe.printStackTrace();
}
return tlist;
}

c. Add the following import statements:

import java.util.*;
import java.rmi.RemoteException;
import javax.ejb.FinderException;
import javax.naming.InitialContext;
import javax.naming.NamingException;

d. Hit Ctrl-S to save.

___ 16. Promote getTxnDataForAccount() method to the Remote Interface

a. While still editing TxnActivityBean.java, select getTxnDataForAccount(int) from the Outline View (it is usually located at the bottom left of the workspace).

b. Click mouse button 2 and choose Enterprise Bean->Promote to Remote Interface. A new method is added to the TxnActivity.java.

___ 17. Add EJB References

In order to be able to lookup other EJBs from the Session EJBs that we have just created, we need to add EJB References in the EJB Deployment Descriptor.

a. From the J2EE Hierarchy view of the J2EE Perspective, double click on EJB Modules->WBOnlineEJB to edit the EJB Deployment Descriptor.

b. From the EJB Deployment Descriptor editor, click on the References tab.

c. From the References page, select AccountActivity and click Add....

d. From the Add Reference dialog, select EJB local reference and click Next> .

e. In the Name field, specify ejb/Customer.

f. In the Link field, click the Browse... button.

g. From the Link Selection dialog, choose Customer from the Link dropdown box and click OK .

h. From the Add EJB Local Reference dialog, verify that you have the following and click Finish:

i. Now, we will add an Account local reference to the TxnActivity Bean. Select TxnActivity and click Add....

j. From the Add Reference dialog, select EJB local reference and click Next> .

k. In the Name field, specify ejb/Account.

l. In the Link field, click the Browse... button.

m. From the Link Selection dialog, choose Account from the Link dropdown box and click OK .

n. From the Add EJB Local Reference dialog, verify that you have the following and click Finish:

o. The References page should be similar to this:

p. Hit Ctrl-S to save and close the EJB Deployment Descriptor Editor.

___ 18. Generate EJB Deployed Code

a. Highlight the WBOnlineEJB module, click mouse button 2, and choose Generate->Deploy and RMIC Code... from the pop-up menu.

b. From the Generate Deploy and RMIC Code dialog, click the Select All button.  Click the Finish button to start the code generation.

Section 4 - Fix Errors in WBOnline Web Module

The generated code for EJB 2.0 specification is quite different from what we had for EJB 1.1 specification. As a result, we need to update some of the source code in the Web Module:

To speed up this process, the updated source code are provided for you. Use the following steps to import the updated source code.

Here's an outline of what has been changed. After importing the updated source code, spend some time to examine them.

___ 1. Delete the existing WBOnline Project

a. From the J2EE Navigator View of the J2EE Perspective, click mouse button 2 on WBOnline and choose Delete... from the popup menu.

b. From the Delete Module Options dialog, verify that Delete selected project(s) only is selected and click OK.

c. From the Confirm Project Delete dialog, select Also delete contents under x:\workbench\WBOnline and click Yes.

___ 2. Import updated WBOnline.war

a. Choose File->Import... from the menu bar.

c. From the Import dialog, select WAR file and click Next>.

d. From the Enterprise Application Import dialog, specify the following:

Parameter Value
WAR File x:\WS50STEW\hands-on\Migration\Part_III\J2EE13\WBOnline.war
Web Project New
New project name WBOnline
Enterprise application project Existing
Existing project name WBOnlineEAR

e. Click Finish .  (Note: Click the Yes button for any message boxes which appear).

___ 3. Add the Utility Jar to WBOnline Project Properties

a. From the J2EE Hierarchy View, expand Web Modules and click mouse button 2 on WBOnline and choose Properties.

b. From the Properties for WBOnline dialog, select Java JAR Dependencies on the left-hand pane and select both the WBOnlineEJB.jar and WBOnlineUtility.jar .

c. Click Apply to apply the changes.

Note: You may need to uncheck and check the JARs listed under Java JAR Dependencies.

d. Click OK.

Section 5 - Run WBOnline in WAS 5.0 Unit Test Environment

___ 1. Delete the v4 data source

To define the v5 datasource using the same JNDI name (ie. jdbc/AIS), we need to delete the v4 data source first.

a. From the Server Configuration view of the Server Perspective, expand Server Configurations and select WebSphere v5 Unit Test.  ( Note: By default, this is in the lower left hand corner of the workbench)

b. Click mouse button 2, and choose Open from the pop-up menu.  This will launch the server configuration editor in the source view.

c. From the WebSphere v5 Unit Test configuration editor, click on the Data source tab.

d. Select the AIS data source and hit the Remove button.

___ 2. Add the jdbc/AIS DataSource to the WebSphere 5.0 server configuration
We will create a WAS v5 datasource in the following steps.

d. From the JDBC provider list in the Node Settings Section, select DB2JDBCProvider .

f. With the DB2JDBCProvider selected, click the Add... button to the right of the Data source defined in the JDBC provider selected above.

g. From the Create a Data Source dialog, choose Version 5.0 data source and click Next> .

h. From the Modify Data Source dialog, specify the following:

Parameter Value
Name AIS
JNDI name jdbc/AIS
Description AIS Datasource
Data source helper class name com.ibm.websphere.rsadapter.DB2DataStoreHelper
Use this data source in container managed persistence (CMP) checked

Click Next> .

i. From the Modify Resource Properties dialog, select databaseName from the Resource Properties section and specify the Value as AIS.

j. Click the Finish button.

The Data sources should look similar to this:

h. Hit Ctrl+S to save the changes.

i. Close the WebSphere v5 Unit Test configuration editor.

___ 3. Start the Unit Test Server
a. From the Server Configuration view, select the WebSphere v5 Unit test configuration , click mouse button 2, and choose Add->WBOnlineEAR from the pop-up menu.

b. From the Servers view highlight the WebSphere v5 Unit Test server, click mouse button 2, and choose Start from the pop-up menu.

This will publish the project and start the server.  After a few moments, check the console window.  You should see a message saying the Default Server server1 open for e-business.  You should scroll through the console to verify the EJB jar WBOnlineEJB was started.

___ 4. Test WBOnline
a. From the Navigator View, expand the WBOnline and Web Content folders. Highlight Index.html and click mouse button 2 and choose Run on Server... from the pop-up menu.

b. From the Server selection dialog, select the WebSphere v5 Unit Test server.

Click the Finish button.

c. You should now be able to test WBOnline and it should work similarly as before (Note: Choose a Customer # of 1).

___ 5. Stop the Server
a. Close the Web Browser

b. Switch from the Console view to the Servers view.

c. Highlight the WebSphere v5 Unit Test Server instance, click mouse button 2, and choose Stop from the pop-up menu.

Congratulations, you've completed Part III of the migration workshop!