Я следил за кучей учебников по этому бизнесу RMI, чтобы узнать, как это сделать правильно. Учебник Oracle использует SecurityManager
, в то время как большинство других не беспокоит. Некоторые из них удлиняют UnicastRemoteObject
, а другие exportObject
. Некоторые запускают RMIRegistry
снаружи и getRegistry
, а другие createRegistry
.Приложение RMI Server не работает (тихо завершается)
Теперь, я подумал, что было бы полезно для меня, чтобы вишня выбрать из этих вариантов передо мной, так вот что я сделал:
Во-первых, я пошел за безопасность, так почему не?
Во-вторых, я не хотел расширять UnicastRemoteObject
, потому что мой объект не совсем удален, просто есть некоторые удаленные методы. Мне просто не показалось, что у меня, например, есть предложение throws RemoteException
на его конструкторе.
И, наконец, я не хотел запускать реестр извне, потому что я на самом деле не сервер, это просто приложение. Кроме того, я не хотел иметь два/три отдельных места для установки порта для реестра.
Вот мой код для сервера один, (надеюсь) делать вещи, которые я описал:
package server;
import interf.TicTacToeBoard;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class TicTacToeServer
{
private static Registry registry;
public static void main(String[] args)
throws RemoteException, AlreadyBoundException
{
System.out.println("Server is up!");
System.setProperty("java.security.policy", "file:/<policy_file_path>");
if (System.getSecurityManager() == null)
System.setSecurityManager(new SecurityManager());
TicTacToeBoardImpl arena = new TicTacToeBoardImpl();
TicTacToeBoard stub =
(TicTacToeBoard) UnicastRemoteObject.exportObject(arena, 0);
registry = LocateRegistry.createRegistry(TicTacToeBoard.RMI_PORT);
registry.bind(TicTacToeBoard.RMI_NAME, stub);
System.out.println("Waiting for connections.");
}
}
Эта вещь не завершена; но с точки зрения возможности обслуживать удаленный объект, это должно быть. Однако после печати этой строки с "Waiting for connections."
приложение просто тихо завершает работу.
Мое единственное объяснение этому заключается в том, что приложение получает сбор мусора.
Это не приведет к сбору мусора в примере Oracle, поскольку там RMIRegistry запускается как отдельное приложение из серверного приложения, а приложение RMIRegistry содержит ссылку на объект, находящийся внутри серверного приложения.
Он не получает сбор мусора, когда моя реализация extends UnicastRemoteObject
, потому что ... я не знаю. Все, что я знаю, это то, что приложение продолжает работать.
Пожалуйста, исправьте меня, если я ошибаюсь на любом этапе. Кроме того, мой вопрос в том, каковы мои варианты, которые не включают запуск RMIRegistry в качестве отдельного процесса, и моя реализация расширяет UnicastRemoteObject
?
Ум, ваш основной метод возвращается, поэтому ваш процесс заканчивается? – bmargulies
Невозможно воспроизвести. @bmargulies № – EJP
У меня такая же проблема. Мне действительно нужно исправить это до крайнего срока. – Tvde1