0
votes

Scenario: I'm implementing an RMI example between 2 PCs where the Controller PC queries the Agent PC for information. The agent PC may run Xen or KVM , hence the implementations of the queries differ(Reason for using RMI). On the Agent's side I'm running 2 RMI registries bound to two different ports. When the same example is carried out with just 1 Registry on the agent's side, everything works fine.

Here is my code: Controller. java(contains main() on controller's side):

public class Controller {

NetworkDiscovery n;
public static int discoveryInterval=2000;
static public PM pmlist;

public static void main(String[] args) throws UnknownHostException,NotBoundException, `   MalformedURLException, RemoteException {

pmOperations pm=(pmOperations)Naming.lookup("rmi://Agent_IP/RMIService1");
boolean l= pm.CreateVM("apple3","/var/lib/libvirt/images",1,200);
System.out.println(l);

vmOperations vm=(vmOperations)Naming.lookup("rmi://Agent_IP/RMIService2");
boolean ShutdownVM = vm.ShutdownVM("apple1");
System.out.println(ShutdownVM);
//other code
}

pmOperations.java(on controller's side)(on the agent's side, it has the same defn with implementation code inside function)

public interface pmOperations extends java.rmi.Remote{
    public boolean CreateVM(String vmName,String imgSrc, int allotCPU, int allotMem )
    throws java.rmi.RemoteException;
}

vmOperations.java(on controller's side)(on the agent's side, it has the same defn with implementation code inside function)

public interface vmOperations extends java.rmi.Remote{
    boolean ChangeVMParam(String vmName,String paramName,String paramValue)
    throws java.rmi.RemoteException;
}

Agent.java

public class Agent {

Agent() throws RemoteException, MalformedURLException{
    Registry RMIService1 = LocateRegistry.createRegistry(1099);

    Registry RMIService2 = LocateRegistry.createRegistry(4478);

        vmOperations vmOp = new kvmVM();
        pmOperations pmOp = new kvmPM();

      Naming.rebind("rmi://localhost:1099/RMIService1", pmOp);
      Naming.rebind("rmi://localhost:4478/RMIService2", vmOp);
}

public static void main(String[] args) throws SocketException, UnknownHostException, IOException, LibvirtException {

        System.out.println("Inside main ");
        new Agent();
        //other code
}
}

Error I get while running above code on controller's side-no error on agent side:

Exception in thread "main" java.rmi.NotBoundException: RMIService2 at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:106) at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:386) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250) at sun.rmi.transport.Transport$1.run(Transport.java:159) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:155) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) at java.rmi.Naming.lookup(Naming.java:84) at package1.Controller.main(Controller.java:43)

Thanks!

1
Why? You don't need two Registries on the same host. What's the purpose of that? - user207421
@EJP- The two functions I'm using above- CreateVM and ShutdownVM are placed in two different interfaces which implement RemoteInterface. That's how We've designed it. Even then, is it wrong to start 2 RMI registries on a PC? - P R
It's pointless. Just another thing to go wrong. Just register the object in the same registry twice with two different names. Your current problem may be due to looking up the wrong registry for example: if you only had one you couldn't make that mistake. - user207421
@EJP- So you're asking me to change the code on agent's side to: Registry RMIService1 = LocateRegistry.createRegistry(4478); Registry RMIService2 = LocateRegistry.createRegistry(4478); vmOperations vmOp = new kvmVM(); pmOperations pmOp = new kvmPM(); Naming.rebind("rmi://localhost:4478/RMIService1", pmOp); Naming.rebind("rmi://localhost:4478/RMIService2", vmOp); Right? THis gives me an error that ObjID is already in use - P R
That changed code still creates two registries. Not what I suggested at all. But NB you would certainly have got that exception with the original code too. You can't create two Registries in the same JVM. And you don't need to create two instances of the remote object either. Just bind the same one twice. - user207421

1 Answers

2
votes

You can't create two Registries in the same JVM. You don't need two Registries in the same host. You don't need to create two instances of the remote object.

Just create one Registry, one remote object, and bind it to the Registry twice, once with each name. You don't really need to bind it twice either really either. There's a lot of pointless duplication in this design.