javarmicorba

Is there a Java RMI equivalent of a CORBA IOR?


CORBA has the nice feature that every reference to a remote object can be transformed into a string, the Interoperable Object Reference (IOR), that abstracts details like protocol, host, port, etc., needed to access the remove object. One can pass such IORs inside emails, files, databases, etc. and recreate the object stub inside a completely different process and it works.

Is there an equivalent of an IOR in Java RMI?


Solution

  • RMI protocol (the actual protocol is called JRMP, and RMI is an API that could use other protocols, but I'll use the term RMI for ease of communication) is based on Java serialization, and RMI remote references are transported as serialized objects just like other data transported over RMI. Java serialization format itself is specified, so it can be used across different JVM implementations.

    So an RMI equivalent of a CORBA IOR is a serialized representation of an RMI remote reference. It is not a strict equivalent since CORBA IOR has textual representation, but one can introduce a binary to textual encoding, like Base64.

    An example where this is used is JMX. JMX can work over different protocols, including RMI and IIOP, and defines an URL format that, apart from supporting regular access via naming server, can also support direct access without naming server. Here is how this URL looks like for RMI and for IIOP:

    // JRMP encoded form
    service:jmx:rmi://localhost/stub/rO0ABXNyAC5qYXZheC5tYW5hZ2VtZW50LnJlbW90ZS5ybWkuUk1JU2VydmVySW1wbF9TdHViAAAAAAAAAAICAAB4cgAaamF2YS5ybWkuc2VydmVyLlJlbW90ZVN0dWLp/tzJi+FlGgIAAHhyABxqYXZhLnJtaS5zZXJ2ZXIuUmVtb3RlT2JqZWN002G0kQxhMx4DAAB4cHc5AAtVbmljYXN0UmVmMgAADjE2LjE5Mi4xMjAuMTI5AAANcQAAAAAAAAAIAOgIQgAAAPlXjcJugAEAeA==
    
    // IIOP encoded form
    service:jmx:iiop://localhost/ior/IOR:000000000000003b524d493a6a617661782e6d616e6167656d656e742e72656d6f74652e726d692e524d495365727665723a303030303030303030303030303030300000000000010000000000000068000102000000000f31362e3139322e3132302e31323900000d93000000000019afabcb0000000002578f08b80000000800000000000000000a0000000000000100000001000000200000000000010001000000020501000100010020000101090000000100010100
    

    Here is an example how it can be used. It this example we are starting an RMI based JMX server and getting its encoded RMI reference that we then decode and deserialize. (This is done just for demonstration, JMX client does all that automatically.)

    import sun.management.jmxremote.ConnectorBootstrap;
    
    import javax.management.remote.JMXConnectorServer;
    import javax.management.remote.rmi.RMIServer;
    import java.io.ByteArrayInputStream;
    import java.io.ObjectInputStream;
    import java.util.Base64;
    
    public class Console1 {
        public static void main(String[] args) throws Exception {
            JMXConnectorServer jmxConnectorServer = ConnectorBootstrap.startLocalConnectorServer();
            String encodedJmxRmiReference = jmxConnectorServer.getAddress().getURLPath().substring("/stub/".length());
            ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(encodedJmxRmiReference)));
            RMIServer jmxRmiReference = (RMIServer) in.readObject();
            System.out.println(jmxRmiReference.getVersion());
        }
    }