Praneeth Peiris
Praneeth Peiris

Reputation: 2088

Java RMI:Updating client side objects in the server

I'm trying to implement a middle-ware for group communication in a distributed system using Java RMI.

In there, I need to send an object to the server and modify it. So that changes should be reflected in the client-side.

For example, I will give the most common tutorial in the Oracle web site:

X.java

public class X  implements Serializable, Remote{
    public int x; // defined as public, just be simple.
}

Hello.java

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

public interface Hello extends Remote {

    String sayHello(X c) throws RemoteException;
}

Server.java

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;

public class Server implements Hello {

    public Server() {
    }

    public String sayHello(X c) {
        c.x = 10;
        return "Hello, world!";
    }

    public static void main(String args[]) {

        try {
            Server obj = new Server();
            Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
            LocateRegistry.createRegistry(1099);
            // Bind the remote object's stub in the registry
            Registry registry = LocateRegistry.getRegistry();
            registry.bind("Hello", stub);

            System.err.println("Server ready");
        } catch (Exception e) {
            System.err.println("Server exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

Client.java

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

    public int x = 4;

    private Client() {
    }

    public static void main(String[] args) {

        String host = (args.length < 1) ? null : args[0];
        try {
            Registry registry = LocateRegistry.getRegistry(host);
            Hello stub = (Hello) registry.lookup("Hello");
            X x = new X();
            String response = stub.sayHello(x);
            System.out.println("response: " + x.x);
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

My problem is, even if I update the value for x in object c on the server-side, it is not reflected to the client-side. I simply could use the return to get the updated value, but I'm planning to use this method to implement a multi-cast function for the server.

Can anyone explain why? And If I need to do so, what is the way of doing it?

Upvotes: 1

Views: 4661

Answers (2)

prmottajr
prmottajr

Reputation: 1824

When you use RMI you are having 2 (or more) java virtual machines involved in a given computation, so when you create an object at the client-side and call a method on the server passing this object as an argument the state of the object is serialized and sent through the network. On the server-side, a new object of the same class is created and the state is set on it, but it is a different object with the same values in it. Operating on this clone won't reflect on the original object that is still residing on the source virtual machine.

You could use a rmiregistry on each machine that runs a virtual machine and registering each object to expose it (this is a distributed solution) or you could concentrate all the data objects on the machine that has the rmiregistry (this is a centralized solution, since all objects are on the same machine).

Cheers!

Upvotes: 1

user207421
user207421

Reputation: 310850

RMI isn't magic. It is Remote Method Invocation. You have to call a remote method to get something to happen in a remote place. Just changing a variable and having it magically propagate across a network isn't within the scope of RMI.

Whatever you want to happen remotely has to be defined by methods in your remote interface(s).

Upvotes: 1

Related Questions