1172-1175

Previous Table of Contents Next

Page 1172

The arguments are optional, and the name server uses port 1050 by default. Refer to the JavaIDL documentation for explanations of additional arguments and other information on the name server.

In the context of the Dept example in Listing 52.2, an instance of the implementation can be bound in the name server directly through a simple server process, such as the one shown in Listing 52.3.

Listing 52.3. A simple server process.

 import com.sun.CORBA.iiop.*; import org.omg.CORBA.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import scott.*; public class DeptServer { protected static String ObjectType = "CORBA Example"; public static void main(String[] args) { org.omg.CORBA.ORB    theOrb = null;            try {             // initialize the ORB environment                   theOrb =  org.omg.CORBA.ORB.init(args, null);                   // create an instance of the Dept implementation and connect it                   to the ORB                   DeptImpl DeptServer = new DeptServer();                   theOrb.connect(DBservant);                   // get the root naming context     org.omg.CORBA.Object objRef = theOrb.resolve_initial_references("NameService");                   NamingContext ncRef = NamingContextHelper.narrow(objRef);                   // bind the object in naming                   NameComponent nc = new NameComponent("DeptServer", ObjectType);                   NameComponent path[] = {nc};                   ncRef.rebind(path, DeptServer);                   // wait for invocations from clients                   java.lang.Object sync = new java.lang.Object();                   synchronized (sync) {                 {                          sync.wait();                   }             }             catch (Exception e) {                   e.printStackTrace();         } } } 

The server process initializes the ORB environment, binds an instance of DeptImpl in the root-naming context, and accepts client invocations until the process is terminated . The ORB is initialized using command-line arguments. Valid arguments are

 -ORBInitialHost hostname 

Page 1173

and

 -ORBInitialPort portnum 

The host and port number are used to locate the name server. Suppose that the name server is running on the same machine on the default port. You would start the Dept server with the following command:

 java DeptServer  -ORBInitialPort 1050 

If no host is supplied, the default host is assumed.

This simple server is provided for the sake of example only. In practice, a more generic server process typically is needed. The server might provide authentication services and expose a single-class factory interface that returns references to other server objects, for example.

Accessing Objects from Client Applications

Client applications first must initialize an ORB environment and obtain an initial ORB object reference for an object implementation by using the name service. The ORB initialization for a client is the same for the server, described in the previous section. The host and port number must refer to the location of the name server.

Using the Dept example, a client can use the name service to obtain an initial reference by using this code fragment:

 // initialize the ORB environment theOrb =  org.omg.CORBA.ORB.init(args, null); // get the root naming context org.omg.CORBA.Object objRef = theOrb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); // locate the object NameComponent nc = new NameComponent("DeptServer", "CORBA Example"); NameComponent path[] = {nc}; Dept deptRef = DeptHelper.narrow(ncRef.resolve(path)); 

Note that the client obtains a reference to the public Java interfacenot to the implementation. After the initial reference is obtained, methods can be invoked on the interface reference as if it were local. A client might update a row in the scott.dept table, for example, by using the following code fragment:

 DeptData newvals = new DeptData(20, "IS", "NEW YORK"); try { deptRef.update(newdept); } catch (Exception e) {      // do something } 

Java classes (DeptData in the preceding example) generated from IDL structs can be constructed by the client directly but always must access server-based objects through a public Java interface. The name server is not always required, though. In many cases, methods of server-based

Page 1174

objects return references to other objects. When references to ORB-based objects are obtained through invocations, using the NamingContext and its narrow() method is unnecessary because the reference is obtained directly.

Design Considerations

Although IDL would seem to serve as a logical starting point for a detailed design, CORBA-based applications should not be designed in a language-neutral context. An understanding of the language-specific mapping of the product can be essential to achieving design goals.

Design goals may be performance related , for example. A common optimization strategy is to minimize communications between the client and the server. Using the emp table from the famous Oracle scott schema as an example, it might seem logical to define an interface to this table by using an interface similar to the following:

 module Scott { interface Employee {         attribute long empno;               attribute string ename;               attribute string job;               attribute long mgr;               attribute string hiredate;               attribute double sal;               attribute double comm;               attribute long deptno;              void fetch();         void insert();         void update();         void delete();     }; }; 

The Employee Java implementation class must extend _EmployeeImplBase (generated by idltojava.exe) and implement the _Employee interface, which is generated as the following:

 package Scott; public interface Employee     extends org.omg.CORBA.Object {     int empno() throws org.omg.CORBA.SystemException;     void empno(int arg) throws org.omg.CORBA.SystemException;     String ename() throws org.omg.CORBA.SystemException;     void ename(String arg) throws org.omg.CORBA.SystemException;     String job() throws org.omg.CORBA.SystemException;     void job(String arg) throws org.omg.CORBA.SystemException;     int mgr() throws org.omg.CORBA.SystemException;     void mgr(int arg) throws org.omg.CORBA.SystemException;     String hiredate() throws org.omg.CORBA.SystemException;     void hiredate(String arg) throws org.omg.CORBA.SystemException;     double sal() throws org.omg.CORBA.SystemException;     void sal(double arg) throws org.omg.CORBA.SystemException;     double comm() throws org.omg.CORBA.SystemException;     void comm(double arg) throws org.omg.CORBA.SystemException;     int deptno() throws org.omg.CORBA.SystemException; 

Page 1175

 void deptno(int arg) throws org.omg.CORBA.SystemException;     void fetch();     void insert();     void update();     void delete(); } 

All the accessors must be implemented. These methods are provided because clients hold references to remote objects, so they are unable to access class variables directly. This limitation can have a significant impact on performance because a method is invoked on the remote object each time a property is accessed. A more optimized approach is to separate the data from the interface, as in this example:

 module Employee {     struct EmpData {         long empno;               string ename;               string job;               long mgr;               string hiredate;               double sal;               double comm;               long deptno;     };     interface EmpControl {              EmpData fetch(in long empno);         void insert(in EmpData theEmp);         void update(in EmpData theEmp);         void delete(in long empno);     }; }; 

An IDL struct also is mapped to a Java class. The difference is that a struct does not define an interface, so properties can be set and retrieved directly, no additional implementations are required, and the resulting EmpData class can be constructed directly by the client. In addition to providing improved performance, this version of the IDL simplifies the process of implementing the EmpControl interface and results in a tighter Java class.

In some cases, concurrency issues related to the ORB architecture can cause performance bottlenecks. Suppose that a very high volume of requests is being processed by a single ORB. That ORB can be bogged down performing "bookkeeping" tasks associated with managing object references and processing requests. A common strategy for avoiding these bottlenecks is to separate the ORB components processing requests from the components interfacing with implementations. This allows request brokers and ORB implementations to be distributed across the network as a means of load balancing.

Using the naming service also involves some overhead, both in terms of performance and application code. In many cases, it is useful to bind only class factory objects in naming, which can be used to obtain references to other objects directly without using the naming service.

Previous Table of Contents Next


Oracle Unleashed
Oracle Development Unleashed (3rd Edition)
ISBN: 0672315750
EAN: 2147483647
Year: 1997
Pages: 391

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