Section 13.9. RMI Over IIOP


13.9. RMI Over IIOP

Another approach for connecting RMI objects to non-Java objects is the ability for RMI objects to communicate directly with remote CORBA objects using IIOP , the CORBA network interface protocol.[4] The standard RMI implementation provided with Java uses an RMI-specific protocol, JRMP, to communicate over the network. RMI/IIOP allows RMI objects to use the CORBA network protocol, IIOP, to communicate with other objects. This means that an RMI object using RMI/IIOP can communicate with a remote CORBA object, regardless of the implementation language of the CORBA object. Likewise, a CORBA object can interact with your Java RMI objects directly. This really gives you the best of both worlds, since you can then implement your remote clients using RMI and use either CORBA or RMI/JNI on the server to interface to any native legacy code.

[4] The RMI/IIOP tools and classes became a standard part of the Java core environment as of JDK 1.3. If you are using an earlier version of Java, you need to download the RMI/IIOP tools and libraries from http://java.sun.com/products/rmi-iiop.

In order to convert your RMI objects to use IIOP, you need to make some changes:

  • Any implementation classes should extend javax.rmi.PortableRemoteObject, rather than java.rmi.server.UnicastRemoteObject.

  • All your stub and skeleton classes need to be regenerated using the updated rmic compiler provided with the RMI/IIOP installation. This updated compiler has an -iiop option that produces stubs and ties (ties refers to skeletons in the CORBA vernacular). These stubs and ties handle the link between client and server objects, but use IIOP rather than JRMP.

  • All use of the RMI Naming registry has to be converted to use of JNDI to talk to a CORBA Naming Service. Objects that you export are bound to names in the CORBA Naming Service through the JNDI context, and remote objects you look up are accessed from the Naming Service through the JNDI context.

  • Instead of using the standard Java casting operator on remote objects you look up, use the javax.rmi.PortableRemoteObject.narrow( ) method.

To give you a taste for how to use RMI/IIOP with your RMI classes, let's convert our first Account example to use RMI/IIOP. First, we need to update the AccountImpl class to extend PortableRemoteObject. The following fragment of the IIOPAccountImpl class does that:

 import javax.rmi.PortableRemoteObject; import java.rmi.RemoteException; import java.util.List; import java.util.ListIterator; public class IIOPAccountImpl extends PortableRemoteObject implements Account {  // Remainder of implementation is identical 

We can compile the updated IIOPAccountImpl using the regular Java compiler, then use the extended rmic compiler included with RMI/IIOP to generate IIOP stubs and ties:

     % rmic -iiop -d /home/myclasses IIOPAccountImpl 

This generates an IIOPAccountImpl_Stub class and an IIOPAccountImpl_Tie class, which act as the IIOP stub and tie for the remote object.

In the CORBA world, remote objects are looked up using the CORBA Naming Service, so we need to update the AccountServer class to use JNDI to register an Account object with a CORBA Naming Service, rather than the RMI registry. The updated IIOPAccountReg class looks like this:

     import javax.naming.*;     import java.rmi.*;     public class IIOPAccountReg {       public static void main(String argv[]) {         try {           // Make an Account with a given name           IIOPAccountImpl acct = new IIOPAccountImpl("Jim.Farley");           // Get a reference to CORBA Naming Service using JNDI           Hashtable props = new Hashtable( );           props.put("java.naming.factory.initial",                     "com.sun.jndi.cosnaming.CNCtxFactory");           props.put("java.naming.provider.url", "iiop://objhost.org:900");           Context ctx = new InitialContext(props);           // Register our Account with the CORBA Naming Service           ctx.rebind("JimF", acct);           System.out.println("Registered account.");         }         catch (Exception e) {           e.printStackTrace( );         }       }     } 

Refer to Chapter 7 for details on the properties used to create the JNDI context and what they mean. All you need to glean from this is that we're trying to connect to a naming service running on objhost.org, listening to port 900. Once we are connected, we register the new IIOPAccountImpl object with the naming service using the Context.rebind( ) method.

Finally, we need to update our client so that it works with RMI/IIOP. Instead of using an RMI registry to look up the remote Account object, the client needs to use JNDI to connect to the same CORBA Naming Service that now hosts our Account object and ask for the Account by name. The updated IIOPAccountClient is shown here. Notice that we've also changed the client to use the PortableRemoteObject.narrow( ) method, instead of just casting the object returned from the lookup:

     import javax.naming.*;     import java.rmi.RMISecurityManager;     public class IIOPAccountClient {      public static void main(String argv[]) {        try {        // Lookup account object        Hashtable props = new Hashtable( );        props.put("java.naming.factory.initial",                  "com.sun.jndi.cosnaming.CNCtxFactory");        props.put("java.naming.provider.url", "iiop://objhost.org:900");        Context ctx = new InitialContext(props);        Account jimAcct =          (Account)PortableRemoteObject.narrow(ctx.lookup("JimF"),                                                   Account.class);          // Make deposit          jimAcct.deposit(12000);          // Report results and balance.          System.out.println("Deposited 12,000 into account owned by " +                             jimAcct.getName( ));          System.out.println("Balance now totals: " + jimAcct.getBalance( ));        }        catch (Exception e) {          System.out.println("Error while looking up account:");          e.printStackTrace( );        }      }     } 

In order to register the server object, we need a CORBA Naming Service running, just as we need an RMI registry with standard RMI. The RMI/IIOP package includes a special naming service that is started using the tnameserv utility. This tool is similar to the naming service provided with Java IDL (and discussed in Chapter 14), but this version is a CORBA Naming Service that also provides JNDI access. On objhost.org, we need to start the naming service like so:

     objhost% tnameserv -ORBInitialPort 900 

Now we can run IIOPAccountReg to register the Account object with the naming service, then run our IIOPAccountClient to access the Account and make a deposit. All network communications are now taking place using IIOP rather than the RMI protocol.

13.9.1. Accessing RMI Objects from CORBA

Since our Account object is now speaking IIOP, we can also access it from other, non-Java CORBA clients. First, we need to get an IDL interface for the Account interface, which can be done using the rmic compiler provided with RMI/IIOP. The -idl option generates an IDL mapping of a Java RMI interface using the Java-to-IDL mapping defined by the CORBA standard. With this IDL mapping, we can generate language-specific stubs that allow any CORBA client to talk to our Java remote object. See Chapter 14 for more details on using IDL and generating language-specific interfaces from it.



Java Enterprise in a Nutshell
Java Enterprise in a Nutshell (In a Nutshell (OReilly))
ISBN: 0596101422
EAN: 2147483647
Year: 2004
Pages: 269

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