Reputation: 2088
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
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
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