2013-09-13 2 views
3

Я создал проект клиент/сервер с использованием Java RMI. Ниже я показываю части реализации. Я запустить сервер с помощьюЗавершить приложение сервера 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 { 
    // ... 
} 

ответ

3

Вы должны добавить интерфейс RMIService самостоятельно writtem доступный в RMIServer так, что программа, которая хочет, чтобы остановить запущенный сервер инструктирует его остановить.

Ваше приложение, которое пытается остановить сервер, просто отталкивает какой-либо объект, так как это не работает сам процесс сервера rmi, он не будет иметь большого эффекта.

Если ваш rmi sever является процессом a, вы должны написать приложение (используя rmi), запущенное как процесс b, чтобы отправить сообщение для обработки a, чтобы остановить его.

+0

Большое спасибо за указание на меня в правильном направлении. Я добавил следующую строку 'UnicastRemoteObject.unexportObject (this, true);' в метод 'quit' класса' MyServant' и перестроил 'stopServer', чтобы вызвать этот метод' quit'. – LaDude

Смежные вопросы