is it possible to pass by reference in RMI?

MBZ picture MBZ · Jun 25, 2012 · Viewed 11k times · Source

I have read various articles about passing variables around using RMI.

Some of them say that it is impossible to pass variables by references in RMI. e.g.: this one and this one

While others says that it is possible. e.g.: this one, this one and this one

can anyone clear this up please? :)

Answer

helios picture helios · Jun 25, 2012

Important note: if pass by reference means modifying argument value inside the method and change original variable in caller, you can't. If what you want to do is passing a copy of a reference to an object, to allow the method interact with some object of yours... yes you can. The answer explores that second option.

Yes. But it has to be an RMI object. In that case a RMI stub will be passed by copy.

RMI passes arguments and return values two ways:

  1. copy the full object
  2. send a remote reference (it has to be remote if its a reference!).

Sample

Guess we have a Service. It's a RMI object, published through the RMI registry, so it's accesible to clients. Client can call a method on it (to create something) and the service wants to return a reference to that newly created object. Not a serialized copy but a reference to the created object in server memory space.

import java.rmi.Remote;
import java.rmi.RemoteException;

// normally published object
public interface MyService extends Remote
{
    // creates something and return a "handle" to it
    public MyHandle createX(SomeSerializableObj param1) throws RemoteException;
}

// interface for object that the service will return a reference to...
public interface MyHandle extends Remote
{
    void doOne();
    void doTwo();
}

In this example you could:

Create an implementation of MyService and publish it

Registry registry = LocateRegistry.createRegistry(port);
MyService stub = (MyService) UnicastRemoteObject.exportObject(server, 0);
registry.bind("myService", stub);`

and then, some RMI client could get a reference to it

Registry registry = LocateRegistry.getRegistry(server, port);
MyService serv1 = (MyService) registry.lookup("myService");

and with a reference to the service object could obtain a reference to other RMI object.

MyHandle handle1 = serv1.createX(...);
handle1.doOne()

In this example the method argument is serialized (it should be a Serializable class) while the returned object is a RMI reference to an object created in the server.

The implementation of createX(...) could be:

public MyHandle createX(...) {
   MyHandle handle = new MyHandleImpl(); // create an implementation
   createdHandlers.add(handle); // add it to some structure (just a sample)
   return handle; // return the implementation. RMI will send to client a RMI reference to this very instance
}