RMI-IIOP
From Wikipedia, the free encyclopedia
RMI-IIOP (read RMI over IIOP) denotes the Java RMI interface over the CORBA system.
This standard was created trying to simplify the development of the CORBA applications, while preserving all major benefits. RMI-IIOP is largely based on the Object by Value concept (described in the CORBA page) that serves as a container or direct replacement for the CORBA structures, unions, sequences, arrays and strings. The IDL is not used. Instead, the data structure definitions "supposed" automatically, collecting the necessary data via reflection mechanisms. When CORBA usually needs a supplementaty generated classes for each non trivial data structure being transferred, RMI-IIOP only uses the generated code for remote objects. Less generated code results the smaller footprint.
Both CORBA and RMI-IIOP use the same GIOP communication standard. If required, it is possible to generate the IDL definitions for the involved RMI-IIOP data structures and use these definitions to arrange the interoperability between the RMI-IIOP and plain CORBA applications.
The recent versions of the RMI-IIOP derive their servants from the standard Servant (CORBA) class. Hence it is possible to connect them to the CORBA ORB manually, involving, if necessary, the Portable Object Adapter, Portable Interceptors, CORBA naming service and all other standard CORBA features.
Contents |
[edit] Hello world example (java)
The standard name for Java RMI-IIOP implementation package is javax.rmi.CORBA.
[edit] The interfaces
public interface MyServer extends Remote { // The client passed self as the first parameter. The server can call the // remote method on the client. This is useful when the request processing takes // a lot of time. void receiveRequest(MyClient client, String message) throws RemoteException; }
public interface MyClient extends Remote { // This remote method is called by the server. void receiveReply(String message) throws RemoteException; }
[edit] The client and server implementations, providing the functionality.
public class MyServerImpl implements MyServer { void receiveRequest(MyClient client, String message) throws RemoteException { System.out.println("The client says: "+message); client.receiveReply("Yes, "+message+", "+message+", "+message+"..."); } }
public class MyClientImpl implements MyClient { MyServer server; public MyClientImpl(String Server_IOR, ORB orb) throws Exception { server = (MyServer) PortableRemoteObject.narrow( orb.string_to_object(Server_IOR), MyServer.class); } // This is a remote method. void receiveReply(String message) throws RemoteException { System.out.println("And the answer is: "+message); } // This is not a remote method, it is a local method. public void talk(String conversation) { server.receiveRequest(this, conversation); } }
The RMI-IIOP developing tool, usually called rmic, will use the two classes above and will create two stubs (for use on remote side) and the two ties (for use on the serving side), one pair for the server and another pair for the client.
[edit] The code, required to start the server
new Thread() { public void run() { try { // Create the CORBA ORB. MyServerImpl.orb = ORB.init(args, properties); // Obtain the root Portable Object Adapter: POA rootPOA = POAHelper.narrow (MyServerImpl.orb.resolve_initial_references("RootPOA")); // MyServerImpl contains the implementation of // the methods that our server must support. MyServerImpl impl = new MyServerImpl(); PortableRemoteObject.exportObject(impl); // Construct the tie that is also the Servant. // The class _MyServerImpl_Tie is generated automatically from the MyServerImpl. Tie tie = new _MyServerImpl_Tie(); // Set the invocation target for this tie. tie.setTarget(impl); // Obtain the reference to the corresponding CORBA object: org.omg.CORBA.Object object = rootPOA.servant_to_reference((Servant) tie); // Activate the root POA. rootPOA.the_POAManager().activate(); // Get the IOR URL that must be passed to clients. String Server_IOR = MyServerImpl.orb.object_to_string(object); MyServerImpl.orb.run(); // The content of the string variable Server_IOR must be somehow transferred // to our client. } catch (Exception exc) { exc.printStackTrace(); } } }.start();
[edit] The code, required to start the client
MyClient the_client; new Thread() { public void run() { try { ORB orb = ORB.init(args, parameters); the_client = new MyClientImpl(Server_IOR, orb); POA rootPOA = POAHelper.narrow(desk.orb.resolve_initial_references("RootPOA")); rootPOA.the_POAManager().activate(); // Construct the tie. Tie tie = new _MyClientImpl_Tie(); // Set the implementing class (invocation target). tie.setTarget(the_client); // Connect the tie as POA servant. org.omg.CORBA.Object object = rootPOA.servant_to_reference((Servant) tie); // The value of the string IOR can be used to find this object on the web String IOR = desk.orb.object_to_string(object); orb.run(); } catch (Exception exc) { exc.printStackTrace(); } } }.start();
Now, somewhere in the code, after the ORB thread has already started, we may call:
the_client.talk("it is raining");
[edit] Executing
The server (first) and the client (second) are started on the two different machines (or as a two separate processes on the same machine). The server prints The client says: it is raining. The client prints And the answer is: Yes, it is raining, it is raining, it is raining...
The suggested Hello world example code must work with Sun Microsystems java 1.5 and GNU Classpath 0.19 (use the discussion tab to report if they do not). Due later fixed bugs the examples will not work with the older releases of these two platforms.
[edit] Legal status of the abbreviation
IIOP is the registered OMG mark and should be used with care. As this protocol is put on the top of GIOP, in some cases it may be recommended to say that the application uses or implements GIOP. This would be true, just less accurate (it is possible to implement GIOP in more ways). See GIOP for more details.