This sample takes you through the creation and deployment of a simple JPA application, Bank. In the sample application Bank, we will use an Enterprise Bean and simple JavaServer Pages to create a simple on-line bank application. In the sample, we can create an account and view the details of the account.

A single Enterprise Bean, Account.java is used in this JPA application with a thin HTML client brought about by three JavaServer Pages.

The walkthrough demonstrates the following:

  • Creating the Project/Directory structure
  • Writing an Enterprise JavaBean File
  • Writing JSP Pages
  • Creating Tables Using the Derby database
  • Deploying the application on Dekoh Desktop
  • Launching the JSP

In this sample, a Windows platform is assumed. To work on any other platform, follow the required file conventions on that platform.

Creating a Directory Structure

  1. Create the following directory structure under C:/ drive.
Bank
- entity
- META-INF
- web/WEB-INF/classes
- web/WEB-INF/lib

Creating the Entity Class

  1. Under the Bank/entity directory, create a new file and name it Account.java. Copy the following code into this file.
/*
 * Copyright (c) 2005 Pramati Technologies Private Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of Pramati
 * Technologies. You shall not disclose such Confidential Information and shall
 * use it only in accordance with the terms of the source code
 * license agreement you entered into with Pramati Technologies.
 *
 */

package entity;

import javax.persistence.*;
/**
 * @author <a href="mailto:abc@pramati.com">ABC</a>
 * @version $Revision: 1.12 $, $Date: 2007/06/29 05:16:21 $, $Author: root $
 * @since Jan 30, 2007
 */
@Entity
@Table(name="ACCOUNT_TABLE")
public class Account
{

	private int id;
	private String Name;
	private double balance;


	public double getBalance()
	{
		return this.balance;
	}

    public void setBalance(double balance)
	{
		this.balance = balance;
	}

    @Id
	@GeneratedValue
	public int getId()
	{
		return this.id;
	}

	public void setId(int id)
	{
		this.id = id;
	}

	
	public String getName()
	{
		return this.Name;
	}

	public void setName(String name)
	{
		this.Name = name;
	}
}

Adding JSP Files to your Directories

  1. JSPs deliver dynamic content to Web clients (standard Web browsers). Follow the steps below to create three simple JSPs.
  2. Under the directory, Bank/web, create a new file, and copy the following code into the file. Save the file as index.jsp.
<html>
<h2>Welcome to Simple Bank Application </h2>
<h3>Create Account</h3>

<form name="CreateForm" method="post" action="createAccount.jsp">
<pre>
Name	: <input type="text" name="name" value=""/>
Balance : <input type="text" name="bal" value=""/>
</pre>
<input type="submit" value="Create Account"/>
</form>

<br><br>
<h3>View Account Details</h3>
<form name="ViewForm" action="viewAccount.jsp"/>
<pre>
Enter your AccountNumber : <input type="text" name="actNumber" value=""> <br>
</pre>
<input type="submit" value = "View Account"/>
</form>
</html>
  1. You will also need to create two more JSP files for the application.
  2. Under the directory, Bank/web, create a new file and copy the following code into it. Save the file as createAccount.jsp.
<%@ page import="javax.persistence.*"%>
<%@ page import="entity.Account" %>

<%
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("account-persistence-unit");
    EntityManager em = emf.createEntityManager();

    String name = request.getParameter("name");
    double balance = Double.parseDouble(request.getParameter("bal"));

    em.getTransaction().begin();
    Account act = new entity.Account();
    act.setName(name);
    act.setBalance(balance);
    em.persist(act);
    em.getTransaction().commit();
    pageContext.setAttribute("act", act);
%>

You have created the account Successfully!
Here are the Details: <br>
<b>Account Number : </b> <%= act.getId()%> <br>
<b>Name 		  : </b> <%= act.getName() %> <br>
<b>Balance 		  : </b> <%= act.getBalance() %> <br>

<a href ="index.jsp"> Home </a>
The file creates a new account for the user with the specified name and balance. The class also sets a unique account ID for each account created.
  1. Create a third JSP file under the directory, Bank/web to view the account created. Copy the following code into the file and save it as viewAccount.jsp. This JSP file is used to display a user’s bank account details for a specific account number.
<%@ page import="javax.persistence.* , entity.*;" %>

<%
 	String actID = request.getParameter("actNumber");
	 EntityManagerFactory emf;
	 EntityManager em;

	emf = Persistence.createEntityManagerFactory("account-persistence-unit");
	em = emf.createEntityManager();
	em.getTransaction().begin();
	Account act = em.find(Account.class , Integer.parseInt(actID.trim()));
	em.getTransaction().commit();
%>

Here are the Details: <br>
<b>Account Number : </b> <%= act.getId()%> <br>
<b>Name 		  : </b> <%= act.getName() %> <br>
<b>Balance 		  : </b> <%= act.getBalance() %> <br>
  1. Under the Bank/web/Web-INF directory, create a new file. Copy the following code and save it as web.xml. A deployment descriptor file typically provides configuration and deployment information (such as welcome file, listener class etc.) for the web components that comprise the application.
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">

	<welcome-file-list>
		<welcome-file>web/index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

Adding Resources to use the Derby Database Server

As part of the JPA application development efforts, you will also need a database to persist the data. In our sample application here, we will use the database, Apache Derby.

To use any other database, you will need to use different resources, and modify the scripts, entity files and tables for the application.

  1. Under the web\WEB-INF\lib folder, save the Derby JAR (derby.jar).
  2. Under the Bank\META-INF folder, create a new file. Copy the following code into the file and save it as persistence.xml. This persistence descriptor file is used to define all the persistence units to be used in your JPA application.
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="account-persistence-unit">
<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
         <class>entity.Account</class>
        <properties>
            <property name="toplink.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
            <property name="toplink.jdbc.url" value="jdbc:derby:C:/Bank/bank_db;create=true"/>
            <property name="toplink.jdbc.user" value=""/>
            <property name="toplink.jdbc.password" value=""/>
            <property name="toplink.logging.level" value="INFO"/>
        </properties>
    </persistence-unit>
</persistence>

Creating Tables Using TopLink Essentials JAR

You may choose to create database tables using some tool, create it programmatically using JPA, or use the JAR file, toplink-essentials.jar.

In the following steps, we explain how to use the TopLink Essentials JAR to automatically create database tables.

  1. Under the web\WEB-INF\lib folder, save the TopLink Essentials JAR (toplink-essentials.jar).

The toplink-essentials.jar is basically the JPA provider for the EJB 3.0 Reference Implementation. In addition to being JPA compliant, it also provides additional extensions beyond what is defined in the JPA specification. For example, TopLink JPA Extensions for JDBC.

  1. You will next need to add/configure persistent units in the persistence.xml file for the TopLink Essentials JAR to automatically create tables.
  2. Open the persistence.xml file that you have already created and add the following line of code inside the properties tag.
<property name="toplink.ddl-generation" value="create-tables"/>
This allows the toplink-essentials.jar file to automatically create DDL for non-existent tables and leave the existing tables unchanged whenever you run the application.

Adding Other JARs

  1. Under the web\WEB-INF\lib folder, save the other required JARs - jsp-api.jar and servlet-api.jar.

Creating .bat Files

  1. Create a new file called build.bat under the rot directory, Bank with the following code:
del entity\*.class
javac entity\*.java
mkdir web\WEB-INF\classes\entity
mkdir web\WEB-INF\classes\META-INF
copy entity\*.class web\WEB-INF\classes\entity
copy META-INF\* web\WEB-INF\classes\META-INF
  1. Set the classpath for all four JARs in the application. You can do this by creating a new file called classpath.bat under the root directory, Bank.
set classpath=C:\Bank\web\WEB-INF\lib\derby.jar;C:\Bank\web\WEB-INF\lib\jsp-api.jar;C:\Bank\web\WEB-INF\lib\toplink-essentials.jar;C:\Bank\web\WEB-INF\lib\servlet-api.jar;
Here, we assume c:\Bank to be the application root directory. You may change this to whatever appropriate on your machine.

Compiling the Java File

  1. Ensure that you set the PATH correctly to use the correct version of JDK ( JDK 1.5 or higher).
  2. At the command prompt, navigate to the Bank directory.
  3. Set the classpath for all the JARs in the application by typing
classpath.bat 
in the command prompt.
  1. Execute the build.bat file by typing
build.bat
in the command prompt.
  1. Executing the build.bat file creates directories under the web/WEB-INF/classes folder, compiles the enterprise java source file, Account.java , stores the compiled classes under the web/WEB-INF/classes directory and also copies some specific files into the classes folder.
  2. After you execute the build.bat file, ensure that all the tasks mentioned in build.bat file have been executed as desired.
  3. Your application is now ready to be deployed.

Deploying the Application

  1. At the command prompt, navigate to the C:/Dekoh/server/bin directory by typing
cd c:\Dekoh\server\bin
  1. Start the Dekoh Desktop using the dekoh_shell.bat command. Linux users, use dekoh_shell.sh command. (If you have the Dekoh Desktop already running, you must shut it down before you use this command to restart the Server.)
  2. At the LWT prompt, type
deploy c:\Bank\web

Running the Application

  1. To run the application, open your default browser and run the index JSP by entering http://localhost:8181/web/index.jsp. In this URL, the Web Module name (web) is the context root of the web application. You can now start creating an account and view the same in your Bank application.

Debugging your Application

This section discusses how to debug the JSP application you just built using IDEs such as IntelliJIDEA and Eclipse SDK. In the following sections, we use the Debugger to:
  • Debug JavaServer Pages remotely
  • View the trace for the specific thread
  • View only source-specific threads for clarity of diagnosis
  • Drill down into objects and watch variables as the code executes

Setting the Java Debug Option

  1. Set the Java debug option in the dekoh_shell.bat or dekoh_shell.sh files by adding
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7777
to the command,
java -server -cp %CLASSPATH% %COMPILER_OPTIONS% %DATEPARSING% %REDIRECTSTREAMS% com.pramati.web.lwt.LWWebServer -nodedir ../nodes/default -httpport 8181 %NOSHELL%

Debug Using Eclipse

  1. To debug your application using Eclipse, you will first need to create your Bank project in Eclipse.
  2. To start the application in the debug mode, click on Run > Debug.. from the main menu. This brings up the Debug dialog where you can configure the debugger settings.
Note: To use remote debugging, you should be using a Java VM that supports this feature.
  1. Start the debugger using a remote launch configuration and specify the address and port of the remote computer. To do this, right click on the Remote Java Application on the left tab and select New. Select the project as Bank, and change the port number to 7777.
  2. Click on Debug to start Dekoh Desktop in the Debug mode.
  3. Deploy the Bank application from the command prompt by typing the following commands:
  • Navigate to the C:/Dekoh/server/bin directory by typing
cd c:\Dekoh\server\bin
  • Start the Dekoh Desktop using the dekoh_shell.bat command.
  • At the LWT prompt, type
deploy c:\Bank\web
  1. Set a breakpoint on an executable line of code for the execution to stop when the control flow reaches the line on which you have set the breakpoint. In this case, inside the file, Account.java, set a breakpoint in the line
this.id = id; 
inside the setId method.
  1. Run the index.jsp file by entering http://localhost:8181/web/index.jsp in your default browser. Start by creating a new account with a name and balance.
  2. Watch the application being debugged in the Eclipse IDE. The Variables tab displays the stack at the point of execution. You can now also perform actions such as step into, step out, changing current thread etc.

Debug Using IntelliJIDEA

  1. To debug your application using IntelliJIDEA, you will first need to create your Bank project in IntelliJIDEA.
  2. To start the application in the debug mode, click on Run > Debug.. from the main menu. This brings up the Debug dialog where you can configure the debugger settings.
Note: To use remote debugging, you should be using a Java VM that supports this feature
  1. Start the debugger using a remote launch configuration and specify the address and port of the remote computer. To do this, right click on the Remote tab and select Add new Configuration. Select the Name as Desktop, and change the port number to 7777.
  2. Click on Debug to start the Dekoh Desktop in the Debug mode.
  3. Deploy the Bank application from the command prompt by typing the following commands:
  • Navigate to the C:/Dekoh/server/bin directory by typing
cd c:\Dekoh\server\bin
  • Start the Desktop Dekoh using the dekoh_shell.bat command.
  • At the LWT prompt, type
deploy c:\Bank\web
  1. Set a breakpoint on an executable line of code for the execution to stop when the control flow reaches the line on which you have set the breakpoint. In this case, inside the file, Account.java, set a breakpoint in the line
this.id = id; 
inside the setId method.
  1. Run the index.jsp file by entering http://localhost:8181/web/index.jsp in your default browser. Start by creating a new account with a name and balance.
  2. Watch the application being debugged in the IntelliJIDEA IDE. Use the Threads tab to view the different threads and stacks at the points of execution. You can also perform actions such as step into, step out, changing current thread etc.

Distributing your Application

Now that you have your application running, you may want to distribute it to end users who have installed Dekoh Desktop, and will like to work with your application.

To make your application distributable to the end user:

  1. Use the pre-compiled JSP Pages that were created when you deployed the application
OR Compile the JSP Pages specifically using ANT
  1. Save the component.xml file
  2. Package the application into deployable archives.

Using the Compiled JSP Pages

  1. When you deploy the JSP application the first time, the compiled classes are stored under the WEB-INF/classes directory. You may use these compiled classes and build your archive.

Compiling the JSP Application Using ANT

  1. To compile the JSP Pages, you may also use ANT. Before using ANT, ensure that you have set the path correctly for ANT.
  2. Copy the following code into a new file.
LIB_DIR = C:\\Dekoh\\server\\lib
pramati.lwt.jar = ${LIB_DIR}/pramati/pramati_web_lwt.jar
app.root=C:/Bank
web.root = ${app.root}/web
class.dir = ${app.root}/web/WEB-INF/classes
ant.class.path = ${pramati.lwt.jar}
app.class.path = ${pramati.lwt.jar}:\
${web.root}/WEB-INF/lib/derby.jar:\
${web.root}/WEB-INF/lib/servlet-api.jar:\
${web.root}/WEB-INF/lib/jsp-api.jar:\
${web.root}/WEB-INF/lib/toplink-essentials.jar:\
${class.dir}:
  1. Change the application path
app.path=C:/Bank 
to point to your Bank root directory.
  1. Save the file as das-jsp-compile.props.
  2. Copy the following code into a blank file and save it as das-jsp-compile.xml. Ensure to save this file in the same directory as das-jsp-compile.props.
<?xml version="1.0" encoding="UTF-8"?>
<project name="Bank" default="instrument">
    <property file="das-jsp-compile.props"/>
	
    <taskdef classname="com.pramati.tools.ant.AntTaskHandlerJSPCompiler" name="jspc">
        <classpath id="jspc.classpath">
            <pathelement path="${app.class.path}"/>
        </classpath>
    </taskdef>
    <taskdef classname="com.pramati.tools.ant.AntTaskHandlerInstrument" name="instrument">
        <classpath id="instrument.classpath">
            <pathelement path="${app.class.path}"/>
        </classpath>
    </taskdef>
    	
	<target name="copy.persistence.xml">
        <copy todir="${class.dir}">
            <fileset dir="${app.root}">
                <include name="/META-INF/persistence.xml"/>
            </fileset>
        </copy>
    </target>
	
	<target name ="javacompile" depends ="copy.persistence.xml">
        <delete>
            <fileset dir="${class.dir}" includes="${class.dir}/*.class"/>
        </delete>
	      <javac srcdir="${app.root}" destdir="${class.dir}" includes="entity/*.java" classpath="${app.class.path}"></javac>
	</target>
	
   <target name="parse">
        <jspc appRoot="${web.root}" validateXML="true" outputDir="${web.root}/WEB-INF/jsp_src">
            <classpath>
                <pathelement path="${app.class.path}"/>
            </classpath>
        </jspc>
    </target>
	
    <target name="webcompile" depends="javacompile , parse">
        <mkdir dir="${web.root}/WEB-INF/classes"/>
        <javac destdir="${web.root}/WEB-INF/classes" optimize="off" debug="on" failonerror="false" srcdir="${web.root}/WEB-INF/jsp_src">
            <classpath>
            	<pathelement path="${app.class.path}"/>
            </classpath>
        </javac>
    </target>

	<target name="instrument" depends="webcompile">
        <instrument srcDir="${web.root}/WEB-INF/jsp_src" classDir="${web.root}/WEB-INF/classes"/>
    </target>
</project>
  1. At the command prompt, type
ant -f <full path to das-jsp-compile.xml>
to compile the file, das-jsp-compile.xml

Saving component.xml file

  1. Copy the following code into a new file, and save the file in the Bank root directory. Name the file as component.xml. This code contains some component-specific information for the application you want to distribute, such as the version number, application name, description etc.
The version number in the component.xml file helps the user keep track of the version of the application.
  <?xml version="1.0" encoding="UTF-8" ?> 
- <component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dekoh.com/xmlns/component http://www.dekoh.com/schemas/component.xsd" xmlns="http://www.dekoh.com/xmlns/component" enabled="true">
  <id>http://www.pramati.com/bank</id> 
  <version>1.0</version> 
  <type>application</type> 
  <display-name>Bank</display-name> 
  <description>A simple Bank application that allows you to create a new account and view the details of the account, given the account ID. </description> 
  </component>
The version manager in Dekoh compares your version against the currently available version of the application. This will either tell you that no upgrade is needed, or that an upgrade is recommended.
  1. If you want to define more elements in your component.xml file, use the component.xsd file. The component.xsd file is defined as follows:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:component="http://www.dekoh.com/xmlns/component"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           targetNamespace="http://www.dekoh.com/xmlns/component">
    <xs:element name="callback-classes">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="component:callback-class" maxOccurs="unbounded" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="dependencies">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="component:dependency" maxOccurs="unbounded" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="component">
        <xs:complexType>
            <xs:all>
                <xs:element ref="component:id"/>
                <xs:element ref="component:version"/>
                <xs:element ref="component:type"/>
                <xs:element ref="component:display-name" minOccurs="0"/>
                <xs:element ref="component:description" minOccurs="0"/>
                <xs:element ref="component:updateurl" minOccurs="0"/>
                <xs:element ref="component:downloadurl" minOccurs="0"/>
                <xs:element ref="component:dependencies" minOccurs="0"/>
                <xs:element ref="component:callback-classes" minOccurs="0"/>
            </xs:all>
            <xs:attribute name="enabled" use="optional">
                <xs:simpleType>
                    <xs:restriction base="xs:boolean"/>
                </xs:simpleType>
            </xs:attribute>
            <xs:attribute name="version" use="optional">
                <xs:simpleType>
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="dependency">
        <xs:complexType>
            <xs:all>
                <xs:element ref="component:id"/>
                <xs:element ref="component:maxversion"/>
                <xs:element ref="component:minversion"/>
                <xs:element ref="component:updateurl"/>
            </xs:all>
            <xs:attribute name="type" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
    <xs:element name="description" type="xs:string"/>
    <xs:element name="id" type="xs:string"/>
    <xs:element name="maxversion" type="xs:string"/>
    <xs:element name="minversion" type="xs:string"/>
    <xs:element name="display-name" type="xs:string"/>
    <xs:element name="type" type="xs:string"/>
    <xs:element name="updateurl" type="xs:string"/>
    <xs:element name="downloadurl" type="xs:string"/>
    <xs:element name="callback-class" type="xs:string"/>
    <xs:element name="version" type="xs:string"/>
</xs:schema>

Packaging the Application

  1. At the command prompt, package the Bank application into a WAR by typing the command
jar -cfv Bank.war web/*.jsp web/WEB-INF/classes web/WEB-INF/lib
  1. Your application is now ready to be distributed for the users to deploy.