我已经使用 Java RMI 建立了一个客户端/服务器项目。下面我展示了部分实现。我使用启动服务器
ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/C", "start /B java -jar myServer.jar --start);
this.myProcess = processBuilder.start();
我已经向处理命令行调用的服务器添加了一个主要方法。服务器启动并完美运行。客户端能够按照我的预期连接和执行。
当我试图杀死服务器时,我的问题就出现了。这需要从外部完成。先前启动该过程的对象不再可用。要真正停止服务器,服务器类的主要方法调用停止方法(见下文)。此方法现在会终止 RMI,但它至少不会阻止 JVM 运行。该进程仍然可用,需要从任务管理器中终止(在 Windows 上)。
我是否错过了在我的实现中产生这种行为的一些事实。为什么进程不会停止运行?
public class MyServer {
// ...
public void startServer() throws RemoteException {
// the RMI registry
Registry registry;
try {
// find the registry
registry = LocateRegistry.createRegistry(portRMI);
} catch (Exception e) {
// if the registry does not yet exist, try to create a new registry
// entry or use an existing one
registry = LocateRegistry.getRegistry(MyConstants.HOST_NAME, portRMI);
}
// create the object
servantObject = new MyServant();
// bind the object to the server
registry.rebind(MyConstants.SERVER_NAME, servantObject);
}
public void stopServer() throws RemoteException {
try {
// access the service
Registry rmiRegistry = LocateRegistry.getRegistry(MyConstants.HOST_NAME, portRMI);
MyService myService = (MyService) rmiRegistry.lookup(MyConstants.SERVER_NAME);
rmiRegistry.unbind(MyConstants.SERVER_NAME);
// get rid of the service object
UnicastRemoteObject.unexportObject(myService, true);
// get rid of the rmi registry
UnicastRemoteObject.unexportObject(rmiRegistry, true);
} catch (NoSuchObjectException e) {
// ...
} catch (NotBoundException e) {
// ...
}
}
public static void main(String[] args) {
// handle arguments and call either startServer or stopServer
}
}
public class MyServant extends UnicastRemoteObject implements MyService {
// ...
}
public interface MyService extends Remote {
// ...
}