方案: 我正在两台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)
谢谢!
答案 0 :(得分:2)
您无法在同一JVM中创建两个注册表。 您在同一主机中不需要两个注册表。 您不需要创建远程对象的两个实例。
只需创建一个注册表,一个远程对象,然后将其绑定到注册表两次,每个名称一次。你真的不需要两次绑定它。这个设计中有很多无意义的重复。