同一台PC上的两个RMI注册表,NotBoundException

时间:2011-10-12 03:58:05

标签: java rmi

方案: 我正在两台PC之间实现一个RMI示例,其中Controller PC向Agent PC查询信息。代理PC可以运行Xen或KVM,因此查询的实现不同(使用RMI的原因)。 在代理方面,我运行了两个绑定到两个不同端口的RMI注册表。当在代理端只使用1个注册表执行相同的示例时,一切正常。

这是我的代码: 控制器。 java(在控制器端包含main()):

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(在控制器方面)(在代理方面,它与函数内部的实现代码具有相同的定义)

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

vmOperations.java(在控制器方面)(在代理方面,它与函数内部的实现代码具有相同的定义)

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
}
}

在控制器端运行代码时遇到错误 - 代理端没有错误:

  

线程“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)           在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)           在java.rmi.Naming.lookup(Naming.java:84)           在package1.Controller.main(Controller.java:43)

谢谢!

1 个答案:

答案 0 :(得分:2)

您无法在同一JVM中创建两个注册表。 您在同一主机中不需要两个注册表。 您不需要创建远程对象的两个实例。

只需创建一个注册表,一个远程对象,然后将其绑定到注册表两次,每个名称一次。你真的不需要两次绑定它。这个设计中有很多无意义的重复。