Oracle8i Enterprise JavaBeans Developer's Guide and Reference Release 3 (8.1.7) Part Number A83725-01 |
|
All EJB clients perform the following to instantiate a bean, invoke its methods, and destroy the bean:
create
method on the home interface causes a new bean to be instantiated. This returns a bean reference to the bean's remote interface.
remove
method to destroy the bean.
These steps are completely illustrated by example in Figure 2-1.
As a quick example, suppose that EmployeeHome
is a reference that you have obtained to the home interface of a bean called Employee
. The Employee
home interface must have at least one create
method that lets you instantiate the bean. You create a new instance of the bean on the remote server by coding:
Context ic = new InitialContext(env); EmployeeHome home = (EmployeeHome) ic.lookup(serviceURL + objectName); // lookup the bean Employee testBean = home.create(); // create a bean instance
Then, you would invoke Employee
methods using the usual syntax
testBean.getEmployee(empNumber);
When you use the getEJBHome method to retrieve the home interface given an object reference, you cannot cast the returned object to the home interface's type. Instead, the returned object is of type org.omg.CORBA.Object. Once received, the object is cast to the correct home interface type through the Helper.narrow method. The following shows the Hello example retrieve Hello's home interface using JNDI, creating the remote interface, and then later retrieving the home interface again using the getEJBHome interface. Notice that the HelloHomeHelper.narrow method is used to correctly typecast the home interface:
HelloHome hello_home = (HelloHome)ic.lookup (serviceURL + objectName); Hello hello = hello_home.create (); System.out.println (hello.helloWorld ()); org.omg.CORBA.Object newHome = (org.omg.CORBA.Object) hello.getEJBHome(); HelloHome newHello = HelloHomeHelper.narrow(newHome);
When you implement an EJB or write the client code that calls EJB methods, you have to be aware of the parameter-passing conventions used with EJBs.
A parameter that you pass to a bean method--or a return value from a bean method--can be any Java type that is serializable. Java primitive types, such as int
, double
, are serializable. Any non-remote object that implements the java.io.Serializable
interface can be passed. A non-remote object passed as a parameter to a bean or returned from a bean is passed by value, not by reference. So, for example, if you call a bean method as follows:
public class theNumber { int x; } ... bean.method1(theNumber);
then method1()
in the bean receives a copy of theNumber
. If the bean changes the value of theNumber
object on the server, this change is not reflected back to the client, because of pass-by-value semantics.
If the non-remote object is complex--such as a class containing several fields--only the non-static and non-transient fields are copied.
When passing a remote object as a parameter, the stub for the remote object is passed. A remote object passed as a parameter must extend remote interfaces.
The next section demonstrates parameter passing to a bean and remote objects as return values.
The EmployeeBean
getEmployee
method returns an EmpRecord
object, so this object must be defined somewhere in the application. In this example, an EmpRecord
class is included in the same package as the EJB interfaces.
The class is declared as public, and must implement the java.io.Serializable
interface so that it can be passed back to the client by value, as a serialized remote object. The declaration is as follows:
package employee; public class EmpRecord implements java.io.Serializable { public String ename; public int empno; public double sal; }
This section shows the client code that you can use to send messages to the example bean described above, and get and print results from it. This client code demonstrates how a client:
The first step with any remote object implementation, whether it's pure RMI, or EJBs, or CORBA, is to find out how to locate a remote object. To get a remote object reference you must know:
With EJBs, the initial object name is the name of an EJB home interface, and you locate it using the Java Naming and Directory Interface (JNDI). The EJB specification requires that EJB implementations expose a JNDI interface as the means of locating a remote bean.
JNDI is an interface to a naming and directory service. For example, JNDI can serve as an interface to a file system that you can use to look up directories and the files they contain. Or, JNDI can be used as an interface to a naming or directory service, for example a directory protocol such as LDAP.
This section briefly describes JNDI. The EJB specification requires the use of JNDI for locating remote objects by name.
This section of the manual describes only those parts of JNDI that you need to know to write EJB applications for Oracle8i. To obtain the complete JNDI API (and SPI) specifications, see http://www.javasoft.com/products/jndi.
Sun Microsystems supplies JNDI in the javax.naming
package, so you must import these classes in your client code:
import javax.naming.*;
For the Oracle8i EJB server, JNDI serves as an interface (SPI driver) to the OMG CosNaming service. But you do not have to know all about CosNaming, or even all about JNDI, to write and deploy EJBs for the Oracle8i server. To start, all you must know is how to use the JNDI methods used to access permanently-stored home interface objects and how to set up the environment for the JNDI Context
object.
The remainder of this JNDI section describes the data structures and methods of the javax.naming
package that you will need to access EJB objects.
You use JNDI to retrieve a Context
object. The first Context
object that you receive is bound to the root naming context of the Oracle8i publishing context. EJB home interfaces are published in the database, and are arranged in a manner similar to a file system hierarchy. See Oracle8i Java Tools Reference for more details about the publish
tool.
You get the root naming context by creating a new JNDI InitialContext
, as follows:
Context initialContext = new InitialContext(environment);
The environment
parameter is a Java hashtable. Table 2-2 contains the six properties that you can set in the hashtable that are passed to the javax.naming.Context.
See Chapter 5, "JNDI Connections and Session IIOP Service", for more information about JNDI and connecting to an Oracle8i instance.
Once you have the initial references context, you can invoke its methods to get a reference to an EJB home interface. To do this, you must know the published full pathname of the object, the host system where the object is located, the IIOP port for the listener on that system, and the database system identifier (SID). When you obtain this information--for example, from the EJB deployer--construct a URL using the following syntax:
<service_name>://<hostname>:<iiop_listener_port>:<SID>/<published_obj_name>
For example, to get a reference to the home interface for a bean that has been published as /test/myEmployee
, on the system whose TCP/IP hostname is myHost
, the listener IIOP port is 2481, and the system identifier (SID) is ORCL
, construct the URL as follows:
sess_iiop://myHost:2481:ORCL/test/myEmployee
The listener port for IIOP requests is configured in the listener.ora file. The default for Oracle8i is 2481. See the Net8 Administrator's Guide for more information about IIOP configuration information. See also Chapter 5, "JNDI Connections and Session IIOP Service" for more information about IIOP connections.
You get the home interface using the lookup
method on the initial context, passing the URL as the parameter. For example, if the home interface's published name is /test/myEmployee
, you would code:
... String ejbURL = "sess_iiop://localhost:2481:ORCL/test/myEmployee"; Hashtable env = new Hashtable(); env.put(javax.naming.Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); // Tell sess_iiop who the user is env.put(Context.SECURITY_PRINCIPAL, "SCOTT"); // Tell sess_iiop what the password is env.put(Context.SECURITY_CREDENTIALS, "TIGER"); // Tell sess_iiop to use non-SSL login authentication env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN); // Lookup the URL EmployeeHome home = null; Context ic = new InitialContext(env); home = (EmployeeHome) ic.lookup(ejbURL); ...
Once you have the home interface for the bean, you can invoke one of the bean's create
methods to instantiate a bean. See Chapter 5, "JNDI Connections and Session IIOP Service" for information about granting execution rights. For example:
Employee testBean = home.create();
Then you can invoke the EJB's methods in the normal way:
int empNumber = 7499; EmpRecord empRec = testBean.getEmployee(empNumber);
Here is the complete code for the client application:
import employee.Employee; import employee.EmployeeHome; import employee.EmpRecord; import oracle.aurora.jndi.sess_iiop.ServiceCtx; import javax.naming.Context; import javax.naming.InitialContext; import java.util.Hashtable; public class Client { public static void main (String [] args) throws Exception { String serviceURL = "sess_iiop://localhost:2481:ORCL"; String objectName = "/test/myEmployee"; int empNumber = 7499; // ALLEN Hashtable env = new Hashtable(); env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi"); env.put(Context.SECURITY_PRINCIPAL, "scott"); env.put(Context.SECURITY_CREDENTIALS, "tiger"); env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN); Context ic = new InitialContext(env); EmployeeHome home = (EmployeeHome) ic.lookup(serviceURL + objectName); // lookup the bean Employee testBean = home.create(); // create a bean instance EmpRecord empRec =
testBean.getEmployee(empNumber); // get the data and print it System.out.println("Employee name is " + empRec.ename); System.out.println("Employee sal is " + empRec.sal); } }
|
Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
|