148.

previous chapter table of contents next chapter
  

A Simple CORBA Example

The standard introductory example to any new system is "hello world." and it seems to get more complex with every advance that is made in computing technology! A CORBA version can be defined by the following IDL:

 module corba {     module HelloModule {         interface Hello {             string getHello();         };     }; }; 

This code can be compiled into Java using a compiler such as Sun's idltojava (or another CORBA 2.2 compliant compiler). This results in a corba.HelloModule package containing a number of classes and interfaces. Hello is an interface that is used by a CORBA client (in Java).

 package corba.HelloModule; public interface Hello     extends org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity {     String getHello(); } 

CORBA Server in Java

A server for the hello IDL can be written in any language with a CORBA binding, such as C++. Rather than get diverted into other languages, though, we will stick to a Java implementation. However, this language choice is not forced on us by CORBA.

The server must create an object that implements the Hello interface. This is done by creating a servant that inherits from the HelloImplBase and then registering it with the CORBA ORB (Object Request Broker ”this is the CORBA backplane , which acts as the runtime link between different objects in a CORBA system). The servant is the CORBA term for what we have been calling the "backend service" in Jini, and this object is created and run by the server. The server must also find a name server and register the name and the servant implementation. The servant implements the Hello interface. The server can just sleep to continue existence after registering the servant.

 /**  * CorbaHelloServer.java  */ package corba; import corba.HelloModule.*; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class CorbaHelloServer {     public CorbaHelloServer() {     }     public static void main(String[] args) {         try {             // create a Hello implementation object             ORB orb = ORB.init(args, null);             HelloImpl hello = new HelloImpl();             orb.connect(hello);             // get the name server             org.omg.CORBA.Object objRef =                 orb.resolve_initial_references("NameService");             NamingContext namingContext = NamingContextHelper.narrow(objRef);             // bind the Hello service to the name server             NameComponent nameComponent = new NameComponent("Hello", "");             NameComponent path[] = {nameComponent};             namingContext.rebind(path, hello);             // sleep             java.lang.Object sleep = new java.lang.Object();             synchronized(sleep) {                 sleep.wait();             }         } catch(Exception e) {             e.printStackTrace();         }     } } // CorbaHelloServer class HelloImpl extends _HelloImplBase {     public String getHello() {         return("hello world");     } } 

CORBA Client in Java

A standalone client finds a proxy implementing the Hello interface with methods such as one that looks up a CORBA name server. The name server returns a org.omg.CORBA.Object , which is cast to the interface type by the HelloHelper method narrow() (the Java cast method is not used). This proxy object can then be used to call methods back in the CORBA server.

 /**  * CorbaHelloClient.java  */ package corba; import corba.HelloModule.*; import org.omg.CosNaming.*; import org.omg.CORBA.*; public class CorbaHelloClient {     public CorbaHelloClient() {     }     public static void main(String[] args) {         try {             ORB orb = ORB.init(args, null);             // get the name server             org.omg.CORBA.Object objRef =                 orb.resolve_initial_references("NameService");             NamingContext namingContext = NamingContextHelper.narrow(objRef);             // get the Hello proxy             NameComponent nameComponent = new NameComponent("Hello", "");             NameComponent path[] = {nameComponent};             org.omg.CORBA.Object obj = namingContext.resolve(path);             Hello hello = HelloHelper.narrow(obj);             // now invoke methods on the CORBA proxy             String hello = hello.getHello();             System.out.println(hello);         } catch(Exception e) {             e.printStackTrace();         }     } } // CorbaHelloClient 

Jini Service

In order to make the CORBA object accessible to the Jini world, it must be turned into a Jini service. At the same time it must remain in a CORBA server, so that it can be used by ordinary CORBA clients. So we can do nothing to the CORBA server. Instead, we need to build a Jini service that will act as a CORBA client. This service will then be able to deliver the CORBA service to Jini clients .

The Jini service can be implemented as a fat proxy delivered to a Jini client. The Jini service implementation is moved from the Jini server to a Jini client as the service object. Once in the client, the service implementation is responsible for locating the CORBA service by using the CORBA naming service, and it then translates client calls on the Jini service directly into calls on the CORBA service. The processes that run in this, with their associated Jini and CORBA objects, are shown in Figure 18-1.

click to expand
Figure 18-1: CORBA and Jini services

The Java interface for this service is quite simple and basically just copies the interface for the CORBA service:

 /**  * JiniHello.java  */ package corba; import java.io.Serializable; public interface JiniHello extends Serializable {     public String getHello(); } // JiniHello 

The getHello() method for the CORBA IDL returns a string . In the Java binding this becomes an ordinary Java String , and the Jini service can just use this type. The next example (in the "Room-Booking Example" section) will show a more complex case where CORBA objects may be returned. Note that because this is a fat service, any implementation will get moved across to a Jini client and will run there, so the service only needs to implement Serializable , and its methods do not need to throw Remote exceptions, since they will run locally in the client.

The implementation of this Jini interface will basically act as a CORBA client. Its getHello() method will contact the CORBA naming service, find a reference to the CORBA Hello object, and call its getHello() method. The Jini service can just return the string it gets from the CORBA service.

 /**  * JiniHelloImpl.java  */ package corba; import org.omg.CosNaming.*; import org.omg.CORBA.*; import corba.HelloModule.*; public class JiniHelloImpl implements JiniHello {     protected Hello hello = null;     protected String[] argv;     public JiniHelloImpl(String[] argv) {         this.argv = argv;     }     public String getHello() {         if (hello == null) {             hello = getHello();         }         // now invoke methods on the CORBA proxy         String hello = hello.getHello();         return hello;     }     protected Hello getHello() {         ORB orb = null;         // Act like a CORBA client         try {             orb = ORB.init(argv, null);             // get the CORBA name server             org.omg.CORBA.Object objRef =                 orb.resolve_initial_references("NameService");             NamingContext namingContext = NamingContextHelper.narrow(objRef);             // get the CORBA Hello proxy             NameComponent nameComponent = new NameComponent("Hello", "");             NameComponent path[] = {nameComponent};             org.omg.CORBA.Object obj = namingContext.resolve(path);             Hello hello = HelloHelper.narrow(obj);             return hello;         } catch(Exception e) {             e.printStackTrace();             return null;         }     } } // JiniHelloImpl 

Jini Server and Client

The Jini server that exports the service doesn't contain anything new compared to the other service providers we have discussed. It creates a new JiniHelloImpl object and exports it using a JoinManager :

 joinMgr = new JoinManager(new JiniHelloImpl(argv), ...) 

Similarly, the Jini client doesn't contain anything new, except that it catches CORBA exceptions. After lookup discovery, the code is as follows :

 try {     hello = (JiniHello) registrar.lookup(template); } catch(java.rmi.RemoteException e) {     e.printStackTrace();     System.exit(2); } if (hello == null) {    System.out.println("hello null");     return; } String msg; try {    msg = hello.getHello();     System.out.println(msg); } catch(Exception e) {    // a CORBA runtime error may occur     System.err.println(e.toString()); } 

Building the Simple CORBA Example

Compared to the Jini-only examples that have been looked at so far, the major additional step in this CORBA example is to build the Java classes from the IDL specification. There are a number of CORBA IDL-to-Java compilers. One of these is the Sun compiler idltojava , which is available from java.sun.com . This (or another compiler) needs to be run on the IDL file to produce the Java files in the corba.HelloModule package. The files that are produced are standard Java files, and they can be compiled using your normal Java compiler. They may need some CORBA files in the CLASSPATH if required by your vendor's implementation of CORBA. Files produced by idltojava do not need any extra classes.

The Jini server, service, and client are also normal Java files, and they can be compiled like earlier Jini files, with the CLASSPATH set to include the Jini libraries.

Running the Simple CORBA Example

There are a large number of elements and processes that must be set running to get this example working satisfactorily:

  1. A CORBA name server must be set running. In the JDK 1.2 distribution is a server, tnameserv . By default, this runs on TCP port 900. Under Unix, access to this port is restricted to system supervisors. It can be set running on this port by a supervisor, or it can be started during boot time. An ordinary user will need to use the option -ORBInitialPort port to run it on a port above 1024:
     tnameserv -ORBInitialPort 1055 

    All CORBA services and clients should also use this port number.

  2. The Java version of the CORBA service can then be started with this command:
     java corba.CorbaHelloServer -ORBInitialPort 1055 
  3. Typical Jini support services will need to be running, such as a Jini lookup service, the RMI daemon rmid , and HTTP servers to move class definitions around.
  4. The Jini service can be started with this command:
     java corba.JiniHelloServer -ORBInitialPort 1055 
  5. Finally, the Jini client can be run with this command:
     java client.TestCorbaHello -ORBInitialPort 1055 

CORBA Implementations

There are interesting considerations about what is needed in Java to support CORBA. The example discussed previously uses the CORBA APIs that are part of the standard OMG binding of CORBA to Java. The packages rooted in org.omg are in major distributions of JDK 1.2, such as the Sun SDK. This example should compile properly with most Java 1.2 compilers using these OMG classes.

Sun's JDK 1.2 runtime includes a CORBA ORB, and the example will run as is, using this ORB. However, there are many implementations of CORBA ORBs, and they do not always behave in quite the same way. This can affect compilation and runtime results. Which CORBA ORB is used is determined at runtime, based on properties. If a particular ORB is not specified, then it defaults to the Sun-supplied ORB (using Sun's SDK). To use another ORB, such as the Orbacus ORB, the following code needs to be inserted before the call to ORB.init() :

 java.util.Properties props = System.getProperties(); props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORB"); props.put("org.omg.CORBA.ORBSingletonClass",           "com.ooc.CORBA.ORBSingleton"); System.setProperties(props); 

Similar code is required for the ORBS from IONA and other vendors .

Variations in CORBA implementations could affect the runtime behavior of the client: if the proxy expects to use a particular ORB other than the default, then the class files for that ORB must be available to the client or be downloadable across the network. Alternatively, the proxy could be written to use the default Sun ORB, and then may need to make inter-ORB calls between the Sun ORB and the actual ORB used by the CORBA service. Such issues take us beyond the scope of this chapter, though. Vendor documentation for each CORBA implementation should give more information on any additional requirements.

  


A Programmer[ap]s Guide to Jini Technology
A Programmer[ap]s Guide to Jini Technology
ISBN: 1893115801
EAN: N/A
Year: 2000
Pages: 189

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