Intro to Orion, Part 2

Objective

This tutorial picks up where Part 1 left off. Part 1 showed you how to create your first Enterprise Java Bean and JSP, and deploy them on Orion. This guide will show you how to use helper classes and connect to an Oracle database (although t is reasonable to assume that this guide could be adapted for other database management systems in addition to Oracle). This guide also takes an object-oriented approach which runs somewhat contrary to the latest EJB specs (i.e. No entity beans here, folks). Be forewarned. ;)


Getting Started

In order to use this guide, you must have first followed Part 1. If you have not done so, please run through it now.

You must also have Oracle installed, though Oracle and Orion need not be running on the same machine. Find the jdbc\lib folder under your Oracle installation folder. For my installation, it is c:\Oracle\Ora81\jdbc\lib. Copy the .zip files in that folder to c:\orion\lib.

You must create a new user in Oracle. Make sure Oracle is running (See bottom for how to start Oracle), and start up SQL Plus (Start > Programs > Oracle > Application Development > SQL Plus), and enter system/manager as your username/password.
Type create user orionapp identified by orionapp; and press Enter.
Enter grant connect, resource to orionapp;
Enter commit;
Enter connect orionapp/orionapp;

Copy and paste the following SQL code for creating a new table and sequence into SQL Plus:

                           
create table visitor (
visitor_id integer not null,
first_name varchar2(20) not null,
last_name varchar2(30) not null,
email varchar2(60) not null,
constraint pk_visitor primary key (visitor_id));
create sequence visitor_seq increment by 1 start with 1;

Enter commit;


Creating the DBAccess Utility Class

Save the following code in a file named DBAccess.java. Make sure you save it in the orionapp\classes\orionapp\utils\ folder.

package orionapp.utils;

import java.sql.*;
import javax.naming.Context;
import javax.sql.DataSource;

public class DBAccess
{
    private DataSource dataSource = null;
    private Connection con = null;
    private Statement st = null;

    public void getConnection(Context ctx)
    {
        try
        {
            DataSource dataSource = (DataSource)ctx.lookup("jdbc/OraclePooledDS");
            con = dataSource.getConnection();
            st = con.createStatement();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void releaseConnection()
    {
        try
            {
                if (st != null)
                    st.close();
                if (con != null)
                    con.close();
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
    }

    public ResultSet executeQuery(String p_strSql)
    {
        ResultSet rs = null;
        try
        {
            rs = st.executeQuery(p_strSql);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return rs;
    }

    public void executeUpdate(String p_strSql)
    {
        try
        {
            st.executeUpdate(p_strSql);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

The purpose for putting this code into a separate utility class is to eleminate much of the messy database access code from your bean classes. You can later modify this class to give it greater flexibility.


Creating the Object Classes

Save the following code in a file named Visitor.java. Make sure you save it in the orionapp\classes\orionapp\objects\ folder.

package orionapp.objects;

public class Visitor implements java.io.Serializable
{   
    public String   visitorId  = null;
    public String   firstName  = null;
    public String   lastName   = null;
    public String   email      = null;
    
    public Visitor(String vId, String fNam, String lNam, String eml)
    {
        visitorId = vId;
        firstName = fNam;
        lastName  = lNam;
        email     = eml;
    }

    public String display()
    {
        return lastName + ", " + firstName + " (<i>" + email + "</i>)";
    }
}

Save the following code in a file named VisitorSet.java. Make sure you save it in the orionapp\classes\orionapp\objects\ folder.

package orionapp.objects;

import java.util.Vector;

public class VisitorSet implements java.io.Serializable
{   
    public Vector visitorSet = new Vector();
    
    public void add(Visitor vis)
    {
        visitorSet.add(vis);
    }
    
    public boolean isEmpty()
    {
        return visitorSet.isEmpty();
    }

    public String display()
    {
        String rtn = "<TABLE WIDTH=\"400\" BORDER=\"0\">\r\n";
        int Size = visitorSet.size();
        for (int i = 0; i < Size; i++)
        {
            rtn += "<TR><TD>\r\n"+
                ((Visitor)visitorSet.get(i)).display()+
                "</TD></TR>\r\n";
        }
        rtn += "</TABLE></DIV>\r\n";
        return rtn;
    }
}


Modifying the Info Bean

**Note** You do not have to modify InfoHome.java at all.

Modify Info.java, adding the lines in blue to your code.

package orionapp.beans.Info;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;
import orionapp.objects.VisitorSet;

public interface Info extends EJBObject 
{
    public String getMessage(String name) throws RemoteException;
    public void insertVisitor(String firstName, String lastName, String email) throws RemoteException;
    public VisitorSet getVisitorSet() throws RemoteException;
}

The method insertVisitor will insert a new visitor record into the database. The method getVisitorSet will return a VisitorSet object containing the set of visitor records already entered in the database.

Modify InfoBean.java, adding the lines in blue to your code.

package orionapp.beans.Info;

import java.rmi.RemoteException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.InitialContext;
import java.sql.ResultSet;
import orionapp.objects.*;
import orionapp.utils.DBAccess;

public class InfoBean implements SessionBean 
{
    public String getMessage(String name)
    {
        String rtn = "Hello, " + name + "!";
        return rtn;
    }
    
    public void insertVisitor(String firstName, String lastName, String email)
    {
        DBAccess db     = new DBAccess();
        int      vId    = -1;
        
        try
        {
            // use the DBAccess class to get a connection
            db.getConnection(new InitialContext());

            // get a unique primary key value
            ResultSet rs = db.executeQuery("SELECT visitor_seq.NEXTVAL FROM dual");
            if (rs.next())
                vId = rs.getInt(1);

            // add the data to the database
            String sql = "INSERT INTO visitor "+
                "(visitor_id, first_name, last_name, email) values "+
                "(" + vId + ", '" + firstName + "', '" + lastName + "', '" + email + "')";

            db.executeUpdate(sql);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            db.releaseConnection();
        }
    }
    
    public VisitorSet getVisitorSet()
    {
        DBAccess db     = new DBAccess();
        VisitorSet vSet = new VisitorSet();

        try
        {
            // use the DBAccess class to get a connection
            db.getConnection(new InitialContext());

            // select the data from the database
            String sql = "SELECT visitor_id, first_name, last_name, email "+
                "FROM visitor ORDER BY last_name";

            ResultSet rs = db.executeQuery(sql);
            // fill the VisitorSet object with the data
            while (rs.next())
            {
                vSet.add(new Visitor(rs.getString("visitor_id"), 
                                     rs.getString("first_name"),
                                     rs.getString("last_name"),
                                     rs.getString("email")));
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            db.releaseConnection();
        }
        return vSet;
    }
    
  public void ejbCreate() { }
  public void setSessionContext(
      SessionContext ctx) { }
  public void ejbRemove() { }
  public void ejbActivate() { }
  public void ejbPassivate() { }
  public void ejbLoad() { }
  public void ejbStore() { }
}


Creating a New JSP

Now copy this code and save it in a file named visitor.jsp in the orionapp\public_html folder. This is a new JSP that we will add to our application.

<%@ page import="
    javax.naming.*,
    javax.ejb.*,
    java.rmi.*,
    javax.rmi.PortableRemoteObject,
    orionapp.objects.VisitorSet,
    orionapp.beans.Info.*"
%>

<HTML><HEAD><TITLE>Test</TITLE></HEAD>
<BODY>

<%
    // variables for the Info bean
    InfoHome        iHome           = null;
    Info            iBean           = null;
    
    // check for form data
    String          firstName       = request.getParameter("txtFirstName");
    String          lastName        = request.getParameter("txtLastName");
    String          email           = request.getParameter("txtEmail");
    
    // VisitorSet object returned from the Info bean
    VisitorSet      vSet            = null;

    try
    {
        InitialContext ctx = new InitialContext();
        iHome = (InfoHome)PortableRemoteObject.narrow(ctx.lookup("java:comp/env/ejb/orionapp/beans/Info"), InfoHome.class);
        iBean = iHome.create();
    } 
    catch(Exception e)
    {
        e.printStackTrace();
    }
    
    // if form data was submitted....
    if ( (firstName != null) && (lastName != null) && (email != null) &&  
        (!firstName.equals("")) && (!lastName.equals("")) && (!email.equals("")) )
    {
            iBean.insertVisitor(firstName, lastName, email);
%>

Visitor added.  <A HREF="visitor.jsp">OK</A>

<%
    } // end if form data was submitted
    else
    {
        vSet = iBean.getVisitorSet();
%>

<FORM METHOD="get" action="visitor.jsp">
<BR>Enter first name: <INPUT TYPE="text" name="txtFirstName"><BR>
<BR>Enter last name: <INPUT TYPE="text" name="txtLastName"><BR>
<BR>Enter email: <INPUT TYPE="text" name="txtEmail"><BR>
<BR><INPUT TYPE="submit" value="Submit"><BR>
</FORM><BR><BR>

<%
        if (vSet.isEmpty())
            out.println("No visitor records in database");
        else
        {
            out.println("<b>Existing Visitor Records:</b><br>");
            out.println(vSet.display());
        }
    } // end else
%>

</BODY></HTML>


Reassembling the Application

First, you have to compile the new classes. In a DOS window (type cmd under Start > Run), type cd\orionapp\classes to get to your classes folder.

Type javac orionapp\beans\Info\*.java to recompile your Info bean classes.

Now type javac orionapp\objects\*.java
Then javac orionapp\utils\*.java
This will compile your objects and utils classes. It is important that you do all your compiling from the classes folder.

Now type jar cvf objects.jar orionapp\objects\*.class
Then jar cvf utils.jar orionapp\utils\*.class
This assembles your objects and utils packages into objects.jar and utils.jar, respectively.
**Note** I am currently unaware of how to use Sun's deploytool utility to package these JAR files into the application EAR file, or even if it is possible. Therefore, you must manually move these JAR files to the c:\orion\lib folder for Orion to detect them. Also note that Orion does not automatically detect changes to files in the lib folder, so you must shut down, then restart Orion after making changes to these files. If anyone knows a better way to do this, please share your knowledge. =)

In a new DOS window, type deploytool, if you do not have it running already.
**Note** If you experience problems with deploytool at any time, try closing it, moving to your classes directory (cd\orionapp\classes) and running it from there.

In the deploytool console, open the orionapp.ear if it is not already open (you should have saved it in c:\orion\applications).

In the Local Applications window, expand orionapp if public_html is not showing. Click on public_html, then click Add under the Contents window of the General tab. (If you cannot see any files in the Contents window, enlarge the deploytool console.) Set your Root Directory to c:\orionapp\public_html and click on visitor.jsp. Click Add, then Next, then Finish. You have just added the new JSP to your application.

Go to Tools > Update Application Files. Then go to File > Save, and you are done!


Deploying in Orion

Open the data-sources.xml file in the Orion config folder. Add the following block of text before the </data-sources> tag:

        <data-source
                class="com.evermind.sql.DriverManagerDataSource"
                name="Oracle"
                location="jdbc/OracleCoreDS"
                xa-location="jdbc/xa/OracleXADS"
                ejb-location="jdbc/OracleDS"
                pooled-location="jdbc/OraclePooledDS"
                connection-driver="oracle.jdbc.driver.OracleDriver"
                username="orionapp"
                password="orionapp"
                url="jdbc:oracle:thin:@computername:1521:databasename"
                inactivity-timeout="5"
        />

Replace computername with the name of your computer, or the name of the computer on your network that is running Oracle. Replace databasename with the name you gave your database. If you do not remember, go to Start > Programs > Oracle > Database Administration > Oracle Administration Assistant. Under the Tree tab, keep expanding the folders until you see one called "Databases". Expand that one to see the name of your database.

Start up Orion and make sure Oracle is running*.

Test the application by entering http://localhost/orionapp/visitor.jsp as the URL. Enter some data. If all goes well, your new application will work! Congratulations, you have just created a 3-tier J2EE application! Start submitting resumes now. ;)




*If you can connect to SQL Plus, it means Oracle is running (Also, ORACLE.EXE will be a running process in your Task Manager). If Oracle is not running, start it by first following the steps given right above to get the database name, then right-click the database name and select Start Service. Give it a moment to start up.