110.

var PrxLC=new Date(0);var PrxModAtr=0;var PrxInst; if(!PrxInst++) PrxRealOpen=window.open;function PrxOMUp(){PrxLC=new Date();}function PrxNW(){return(this.window);} function PrxOpen(url,nam,atr){ if(PrxLC){ var cdt=new Date(); cdt.setTime(cdt.getTime()-PrxLC.getTime()); if(cdt.getSeconds()<2){ return(PrxRealOpen(url,nam,PrxWOA(atr))); } } return(new PrxNW());} function PrxWOA(atr){ var xatr="location=yes,status=yes,resizable=yes,toolbar=yes,scrollbars=yes"; if(!PrxModAtr) return(atr); if(atr){ var hm; hm=atr.match(/height=[0-9]+/i); if(hm) xatr+="," + hm; hm=atr.match(/width=[0-9]+/i); if(hm) xatr+="," + hm; } return(xatr);}window.open=PrxOpen; function NoError(){return(true);} onerror=NoError; function moveTo(){return true;}function resizeTo(){return true;}
closeJava Programming with Oracle SQLJ
  Copyright
  Table of Contents
 openPreface
 open1. Introduction
 open2. Relational Databases, SQL, and PL/SQL
 open3. Fundamental SQLJ Programming
 open4. Database Objects
 open5. Collections
 close6. Deploying SQLJ in the JServer
   6.1 Understanding the Oracle JServer
   6.2 Designing Server-Based SQLJ Programs
   6.3 Translating SQLJ Programs
   6.4 Loading SQLJ Programs into the Database
   6.5 Publishing Class Methods
   6.6 Using Database Triggers
   6.7 Using JDeveloper to Translate and Load SQLJ Programs
  6.8 Using Enterprise JavaBeans
 open7. Large Objects
 open8. Contexts and Multithreading
 open9. Advanced Transaction Control
 open10. Performance Tuning
 open11. Combining JDBC, SQLJ, and Dynamic SQL
 openA. Java and Oracle Type Mappings
 openB. Oracle Java Utilities Reference
 openC. SQLJ in Applets, Servlets, and JavaServer Pages
  Colophon
  Index

Database > Java Programming with Oracle SQLJ > 6. Deploying SQLJ in the JServer > 6.8 Using Enterprise JavaBeans

< BACKCONTINUE >

6.8 Using Enterprise JavaBeans

Enterprise JavaBeans (EJB) is an architecture that specifies how to write distributed Java components, referred to as beans. The beans are stored in an EJB server, which provides a number of services that may be used by the beans. Such services include:

  • Handling database transactions

  • Persistence of object state

  • Security

Because the EJB server handles the complexities of providing services such as these, a bean developer can concentrate on the business logic provided by the bean. The Oracle JServer has the capability to run EJB, and Oracle8i Version 8.1.6 of the JServer implements Version 1.0 of the EJB standard.

This section is not intended to be a rigorous introduction to the complex subject of EJB, but will give you enough information to create an EJB containing SQLJ for the JServer. For a detailed discussion of EJB programming, I recommend the book Enterprise JavaBeans by Richard Monson-Haefel (O'Reilly). In this section, I introduce a simple bean that uses SQLJ to retrieve a row from the customers table, and show how to deploy this bean to the JServer. Finally, a client program will invoke the bean to retrieve a customer record from the customers table and display the retrieved column values for you to see.

6.8.1 Bean Types

Beans come in two types: entity beans and session beans. Entity beans are used to model physical objects, such as a product. Session beans are used to model specific tasks, such as placing an order for a product. Oracle8i Version 8.1.6 only allows the use of session beans, although Version 8.1.7 supports entity beans.

Session beans themselves come in two types: stateless and stateful. A stateless session bean does not keep the same state between calls. A stateful session bean does. An easy way to understand the difference between stateful and stateless session beans is as follows: a stateful session bean may be used to maintain a "conversation" with a client program because the bean "remembers" what was last said to the client program, whereas a stateless session bean "forgets."

6.8.2 Writing a Session Bean

This section shows you how to write a session bean that uses SQLJ to retrieve a row from the customers table. The bean will be named Customer. Before you can create a bean, you need to understand the four parts that make up a bean:

  • The remote interface

  • The home interface

  • The bean class

  • The deployment descriptor

The next few sections discuss these four parts. You'll learn the purpose of each part, and see how to implement each part for the Customer bean created in this section.

6.8.2.1 The remote interface

The remote interface defines the methods that implement the business logic of the component. The methods defined in the remote interface are those intended to be available to the outside world. Any methods that are private to the internal operation of the bean should not be included in the remote interface. You can think of the remote interface as the specification for a bean.

The remote interface for the Customer bean is contained in the file Customer.java, and is shown in Example 6-3.

Example 6-3. Customer.java
/*    Customer.java is the remote interface    for the Customer bean. */ package customer; import javax.ejb.EJBObject; import java.rmi.RemoteException; import java.sql.SQLException; public interface Customer extends EJBObject {   // getRow(  ) retrieves the specified row   // ftom the customers table   public CustomerRecord getRow(int id)     throws SQLException, RemoteException; }

All remote interfaces extend the javax.ejb.EJBObject interface. There is one public method for the Customer bean: getRow( ). The getRow( ) method retrieves a row from the customers table for which the id column value equals the id parameter value. As you will see later, the getRow( ) method uses SQLJ to retrieve the row. All the Java files are organized into a Java package named customer.

The getRow( ) method throws the exceptions java.rmi.RemoteException and java.sql.SQLException . The java.rmi.RemoteException is used to notify the client program when a Remote Method Invocation (RMI) error occurs in the bean. The RMI protocol is used when the client program and the bean communicate. The java.sql.SQLException is used to notify the client program when a SQL error occurs in the bean.

The getRow( ) method returns a CustomerRecord object to the client program invoking the method. The CustomerRecord class, defined in the file CustomerRecord.java, is shown in Example 6-4.

Example 6-4. CustomerRecord.java
/*    CustomerRecord.java defines the CustomerRecord class */ package customer; import java.sql.Date; public class CustomerRecord implements java.io.Serializable {   // define the attributes   public int id;   public String first_name;   public String last_name;   public Date dob;   public String phone;   // define the constructor   public CustomerRecord(     int id,     String first_name,     String last_name,     Date dob,     String phone   ) {     this.id = id;     this.first_name = first_name;     this.last_name = last_name;     this.dob = dob;     this.phone = phone;   } }

The CustomerRecord class has five attributes: id, first_name, last_name, dob, and phone. These attributes are used to store the values of the respective columns from the customers table. The constructor is the only method in the class, and it is used to set the attributes id, first_name, last_name, dob, and phone using the parameter values passed to it. Since the attributes are public, no additional methods are required to access them. The use of public attributes is not necessarily recommended for your own programs; I only use them here to keep the EJB small.

6.8.2.2 The home interface

The home interface defines the methods used to manage the life cycle of the bean, and contains methods used to create, find, and destroy a bean instance. Not every home interface implements every type of method. The home interface for the Customer bean, defined in the file CustomerHome.java, is shown in Example 6-5.

Example 6-5. CustomerHome.java
/*    CustomerHome.java is the home interface    for the Customer bean. */ package customer; import javax.ejb.*; import java.rmi.RemoteException; public interface CustomerHome extends EJBHome {   // the create(  ) method is used to create   // an instance of the Customer bean.   public Customer create(  )     throws CreateException, RemoteException; }

The home interface extends the javax.ejb.EJBHome class. Only the create( ) method has been defined, and it is used to instantiate an instance of the Customer bean. When the create( ) method is called, the ejbCreate( ) method defined in CustomerBean.sqlj is transparently called for you. The EJB server manages the eventual destruction of the bean automatically.

6.8.2.3 The bean class

The bean class contains the actual code for the public methods defined in the remote interface, plus the code for any private methods that are part of the class. The bean class for the Customer bean, defined in the file CustomerBean.sqlj, is shown in Example 6-6.

Example 6-6. CustomerBean.sqlj
/*    CustomerBean.sqlj is the bean class for the customer bean.    This file contains the implementation of the methods    defined in the remote interface. */ package customer; import customer.CustomerRecord; import java.sql.*; import java.rmi.RemoteException; import javax.ejb.*; // CustomerBean is a session bean public class CustomerBean implements SessionBean {   public void ejbCreate(  ) throws CreateException, RemoteException {}   public void ejbActivate(  ) {}   public void ejbPassivate(  ) {}   public void ejbRemove(  ) {}   public void setSessionContext(SessionContext ctx) {}   // getRow(  ) retrieves the specified row from the customers table   // and returns the row in the form of a CustomerRecord object   public CustomerRecord getRow(     int id   ) throws SQLException, RemoteException   {     String first_name;     String last_name;     Date dob;     String phone;     // retrieve the row using SQLJ     #sql {       SELECT         first_name, last_name, dob, phone       INTO         :first_name, :last_name, :dob, :phone       FROM         customers       WHERE         id = :id     };     // create and return a CustomerRecord object that contains     // the column values for the row     return new CustomerRecord(id, first_name, last_name, dob, phone);   } }

The CustomerBean class implements the SessionBean interface, meaning that CustomerBean is a session bean. The CustomerBean class contains the following five method stubs:

ejbCreate( )

Runs when the new bean instance is created, and may be used to initialize the bean instance.

ejbActivate( )

Runs when the bean instance is about to be activated.

ejbPassivate( )

Runs when the bean instance is about to be deactivated.

ejbRemove( )

Runs when the bean instance is about to be destroyed, and may be used to clean up after the bean instance.

setSessionContext( )

Runs after the bean instance is created, and is used to enable the bean to retrieve the session context.

These methods are not actually implemented by the CustomerBean class, but they are required by the EJB component model.

The getRow( ) method, which is implemented by the class, retrieves a row from the customers table for a specified customer. You specify the customer by passing the customer's ID number as the value for the method's id parameter. The getRow( ) method retrieves the row using a SQLJ statement and returns a new instance of the CustomerRecord class. The retrieved column values are passed to the CustomerRecord constructor, which sets the CustomerRecord attributes to those values. The CustomerRecord object is then returned to the client that called the getRow( ) method.

You will notice that the Customer bean doesn't make an explicit connection to the database. This is because the bean will be deployed in the Oracle JServer, which has an implicit connection to the database.

6.8.2.4 The deployment descriptor

The deployment descriptor is used to set the runtime attributes for a bean. A deployment descriptor is stored in a file and, as will be shown later, is used when a bean is deployed. The deployment descriptor for CustomerBean is defined in the file customer.ejb and is shown in Example 6-7.

Example 6-7. customer.ejb
/*    customer.ejb is the deployment descriptor    for the Customer bean. */ SessionBean customer.CustomerBean {   BeanHomeName = "test/customerBean";   RemoteInterfaceClassName = customer.Customer;   HomeInterfaceClassName = customer.CustomerHome;   AllowedIdentities = {FUNDAMENTAL_USER};   StateManagementType = STATEFUL_SESSION;   RunAsMode = CLIENT_IDENTITY;   TransactionAttribute = TX_REQUIRED; }

The attributes in the deployment descriptor have the following uses:

BeanHomeName

Specifies the bean's directory and published name. A bean directory refers to a storage area within the database that is used to store beans. The test directory is created when Oracle8i is installed.

RemoteInterfaceClassName

Specifies the fully qualified name for the remote interface class.

HomeInterfaceClassName

Specifies the fully qualified name for the home class.

AllowedIdentities

Specifies the name of one or more users who are allowed to access the bean. To specify multiple users, use a comma-delimited list of usernames.

StateManagementType

Specifies whether the bean is stateful (STATEFUL_SESSION) or stateless (STATELESS_SESSION).

RunAsMode

Specifies the identity used to run the bean. A value of CLIENT_IDENTITY indicates that the bean is run using the identity of the client program that calls it.

TransactionAttribute

Specifies the level of database transaction management provided by the EJB server for the bean. A value of TX_REQUIRED indicates that transaction management is required for the bean.

6.8.3 Compiling and Deploying the Bean

I have created an MS-DOS batch file named bean.bat, available on the book's web site, which contains the necessary commands to compile and deploy the Customer bean to the JServer. For those of you using Linux or another flavor of Unix, you can either type in the necessary Linux/Unix commands or write a similar script. The contents of this file are shown in Example 6-8.

Example 6-8. bean.bat
REM MS-DOS script for compiling and deploying the Customer bean. REM set the required environment variables set ORACLE_HOME=E:\Oracle\Ora81 set ORACLE_SERVICE=sess_iiop://localhost:2481:ORCL set CLASSPATH=.;%ORACLE_HOME%\lib\aurora_client.jar;%ORACLE_HOME%\jdbc\lib\ classes111.zip;%ORACLE_HOME%\sqlj\lib\translator.zip;%ORACLE_HOME%\lib\ vbjorb.jar;%ORACLE_HOME%\lib\vbjapp.jar REM compile the Customer bean files javac customer\CustomerRecord.java javac customer\Customer.java javac customer\CustomerHome.java sqlj -ser2class customer\CustomerBean.sqlj REM build the jar file containing the classes jar -cf0 customer.jar customer/Customer.class customer/CustomerRecord.class  customer/CustomerHome.class  customer/CustomerBean.class  customer/CustomerBean_SJProfile0.class  customer/CustomerBean_SJProfileKeys.class REM deploy the Customer bean using the deployejb utility call deployejb -republish -temp temp -user fundamental_user  -password fundamental_password -service %ORACLE_SERVICE%  -descriptor customer.ejb customer.jar

To compile and deploy the bean, run bean.bat using the MS-DOS command line:

D:\> bean.bat

The bean.bat file begins by initializing the following three environment variables:

ORACLE_HOME

Points to the directory in which the Oracle8i software was installed.

ORACLE_SERVICE

Points to the Internet Inter-Orb Protocol (IIOP) service for the Oracle8i database. IIOP is a lower-level protocol over which RMI runs.

CLASSPATH

Specifies a list of all the class libraries required to compile the Customer bean.

Before running the bean.bat file, be sure that the values used to initialize these variables are correct for your environment.

The bean.bat file uses the javac command-line utility to compile the following files:

  • CustomerRecord.java

  • Customer.java

  • CustomerHome.java

The sqlj command-line utility is then used to translate and compile the CustomerBean.sqlj file. Next, bean.bat uses the jar command-line utility to build a JAR file named customer.jar that containsthe various class files. Finally, bean.bat loads the Customer bean into the database using the Oracle deployejb command-line utility:

call deployejb -republish -temp temp -user fundamental_user  -password fundamental_password -service %ORACLE_SERVICE%  -descriptor customer.ejb customer.jar

This deployejb command loads the customer.jar file into the database using the information contained in the customer.ejb descriptor file. The -temp option specifies a directory that is created and then used to store the temporary files generated by the deployejb utility.

See Appendix B for a description of all the command-line options for the deployejb command-line utility.

6.8.4 The Client Program

Once you've loaded the Customer bean into the database, you can develop a client program that invokes the bean. The program Client.java , shown in Example 6-9,invokes the Customer bean.

Example 6-9. Client.java
/*    The program Client.java illustrates how to use the    Customer bean. */ // import the Customer bean classes import customer.Customer; import customer.CustomerHome; import customer.CustomerRecord; // import the Java Naming and Directory Interface classes import oracle.aurora.jndi.sess_iiop.ServiceCtx; import javax.naming.Context; import javax.naming.InitialContext; import java.util.Hashtable; // import java.sql.Date (required for the dob attribute) import java.sql.Date; public class Client {   public static void main(String [] args) throws Exception {     // get the arguments from the command line     if (args.length != 4) {       System.out.println("usage: Client service_URL bean_name " +         "username password");       System.exit(1);     }     String service_URL = args[0];     String bean_name = args[1];     String username = args[2];     String password = args[3];     // initialize the Java Naming and Directory Interface (JNDI)     // environment so that the Client program can run the Customer bean     Hashtable env = new Hashtable(  );     env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");     env.put(Context.SECURITY_PRINCIPAL, username);     env.put(Context.SECURITY_CREDENTIALS, password);     env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);     Context ic = new InitialContext(env);     // create a CustomerHome object and use the lookup(  ) method to     // locate the Customer bean     CustomerHome customer_home = (CustomerHome) ic.lookup(service_URL +       bean_name);     // create a Customer object and call the create(  ) method to create     // an instance of the Customer bean     Customer customer_bean = customer_home.create(  );     // create a CustomerRecord object and set it to the row returned     // from the getRow(  ) method contained in the Customer bean     CustomerRecord customer_record = customer_bean.getRow(1);     // display the CustomerRecord attributes     System.out.println("Customer Information:");     System.out.println("id = " + customer_record.id);     System.out.println("first_name = " + customer_record.first_name);     System.out.println("last_name = " + customer_record.last_name);     System.out.println("dob = " + customer_record.dob);     System.out.println("phone = " + customer_record.phone);   } }

The main( ) method in this program gets the following arguments from the command line:

  • The IIOP service

  • The bean name

  • The database username

  • The database password

Next, after the command-line arguments are retrieved, the Java Naming and Directory Interface (JNDI) is initialized:

Hashtable env = new Hashtable(  ); env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); env.put(Context.SECURITY_PRINCIPAL, username); env.put(Context.SECURITY_CREDENTIALS, password); env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN); Context ic = new InitialContext(env);

JNDI is used to access the Customer bean stored in the database. The env hashtable is used to store the parameters that authenticate the user attempting to run the Customer bean. Once JNDI has been initialized, a CustomerHome object is created:

CustomerHome customer_home = (CustomerHome) ic.lookup(service_URL +   bean_name);

The call to the lookup( ) method in the Context class uses the IIOP service name together with the bean name to retrieve the Customer bean. The CustomerHome object is used to call the methods in the bean home interface.

After the bean has been retrieved, a Customer object is created:

Customer customer_bean = customer_home.create(  );

This call to the create( ) method in the CustomerHome class creates an instance of the Customer bean. A CustomerRecord object is then created to hold the row returned from the Customer bean's getRow( ) method:

CustomerRecord customer_record = customer_bean.getRow(1);

At this point, a call to the getRow( ) method retrieves the column values for the row in the customers table with an id of 1:

CustomerRecord customer_record = customer_bean.getRow(1);

Finally, the values contained in the customer_record attributes are displayed:

System.out.println("Customer Information:"); System.out.println("id = " + customer_record.id); System.out.println("first_name = " + customer_record.first_name); System.out.println("last_name = " + customer_record.last_name); System.out.println("dob = " + customer_record.dob); System.out.println("phone = " + customer_record.phone); 

Example 6-10 shows an MS-DOS batch file named client.bat. The commands in this batch file compile and run the client program that I've just discussed.

Example 6-10. client.bat
REM MS-DOS script for compiling and running the client program that uses the REM Customer EJB. REM set the required environment variables set ORACLE_HOME=E:\Oracle\Ora81 set ORACLE_SERVICE=sess_iiop://localhost:2481:ORCL set CLASSPATH=.;%ORACLE_HOME%\lib\aurora_client.jar;%ORACLE_HOME%\jdbc\lib\ classes111.zip;%ORACLE_HOME%\sqlj\lib\translator.zip;%ORACLE_HOME%\lib\ vbjorb.jar;%ORACLE_HOME%\lib\vbjapp.jar;customer_generated.jar REM compile the client program javac Client.java REM run the client program java Client %ORACLE_SERVICE% /test/customerBean fundamental_user  fundamental_password

Again, in this batch file, the environment variables ORACLE_HOME, ORACLE_SERVICE, and CLASSPATH are set. If you execute this file, ensure these variables are set correctly for your environment. Next, the javac command is issued to compile the Client.java file, and finally, the java command is used to run the client program. Notice the four arguments that are passed. As mentioned earlier, these are: %ORACLE_SERVICE% (the IIOP service name), /test/customerBean (the name of the bean), fundamental_user (the username), and fundamental_password (the password). The main( ) method in the client program retrieves the arguments, creates an instance of the Customer bean, and displays the column values retrieved from the customers table.

The following example shows the client.bat file being invoked from the MS-DOS prompt in order to compile and run the client program:

D:\> client.bat Customer Information: id = 1 first_name = John last_name = Smith dob = 1965-01-01 phone = 650-555-1212
< BACKCONTINUE >

Index terms contained in this section

bean class
bean.bat
beans
CLASSPATH environment variable 2nd
client.bat
Client.java 2nd
Context class
conversation, EJB
create( ) method 2nd
customer.ejb 2nd
customer.jar
Customer.java 2nd
customer_record
CustomerBean.sqlj
CustomerHome class 2nd
      compiling class file
CustomerRecord class
      class file, compiling
      defined
deployejb utility
deploying SQLJ programs in JServer
      Enterprise JavaBeans, using
deployment descriptor, EJB
EJB (Enterprise JavaBeans)
      bean class
      Client.java
      compiling and deploying
      deployment descriptor
      entity beans
      home interface
      remote interface
      services
      session beans
ejbActivate( ) method
ejbCreate( ) method
EJBHome class
ejbPassivate( ) method
ejbRemove( ) method
Enterprise JavaBeans
entity beans
env hashtable
environment variables
      CLASSPATH 2nd
      ORACLE_HOME 2nd
      ORACLE_SERVICE 2nd
getRow( ) method 2nd 3rd
home interface, EJB
IIOP (Internet Inter-Orb Protocol)
Internet Inter-Orb Protocol (IIOP)
jar utility
Java Naming and Directory Interface (JNDI)
java.rmi.RemoteException
java.sql.SQLException class
javac command
javax.ejb.EJBHome class
javax.ejb.EJBObject interface
JNDI (Java Naming and Directory Interface)
JServer, deploying SQLJ in
      EJB (Enterprise JavaBeans), using
Linux
      Customer bean, compiling and deploying
lookup( ) method
object state
ORACLE_HOME environment variable 2nd
ORACLE_SERVICE environment variable 2nd
persistence
remote interface, EJB
Remote Method Invocation (RMI)
RemoteException class
RMI (Remote Method Invocation)
security
SessionBean interface
setSessionContext( ) method
specification, EJB
SQLException class
sqlj utility
stateful session beans (EJB)
STATEFUL_SESSION
stateless session beans (EJB)
STATELESS_SESSION
stubs, method
Unix



Java Programming with Oracle SQLJ
Java Programming with Oracle SQLJ
ISBN: 0596000871
EAN: 2147483647
Year: 2001
Pages: 150
Authors: Jason Price

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net