#java #rmi #serializable
#java #rmi #сериализуемый
Вопрос:
У меня неприятная проблема, но сначала позвольте мне объяснить контекст.
Проект — это всего лишь простой проект, поэтому я знакомлюсь с RMI. Проект представляет собой сервер фондового рынка и клиент, который извлекает данные о фондах с сервера.
Я разделил проект на 3 java-проекта. Сервер (имеющий MockStockMarket и Fund), клиент (имеющий классы GUI и класс для взаимодействия с сервером: BannerController) и проект с интерфейсами, которые нужны как клиенту, так и серверу (IStockMarket и iFund).
Я хочу, чтобы мой bannerController взаимодействовал с биржевым рынком, чтобы bannercontroller получал средства. Это делается с помощью getFunds() : ArrayList .
Как вы можете видеть, StockMarket должен быть удаленным, а Фонд должен быть сериализуемым.
Проблема в том, что по какой-то причине, когда я использую следующий код:
IStockMarket market = new MockStockMarket();
Naming.rebind("rmi://localhost/StockMarket", market);
Как IStockMarket (как предполагалось), так И iFund (не как предполагалось) становятся удаленными. Это не то, чего я хочу.
Для справки: Fund реализует iFund, который расширяет Serializable (то есть ничего удаленного) , а MockStockMarket расширяет UnicastRemoteObject и реализует IStockMarket, который расширяет Remote.
Вот скриншот веб-сервера, публикующего оба интерфейса: http://imageshack.us/m/194/4755/rmibothinterfacespublis.png .
Для исходного кода:https://rapidshare.com/files/2085773800/stockmarket.zip
Ответ №1:
Привязка службы RMI к порту отличается от привязки файлов веб-сервера, публикующего файлы. На скриншоте, который вы прикрепили, показано, что ваш IStockMarket.class и IFund.class файлы предоставляются как HTTP-ресурсы, которые не имеют ничего общего с «привязкой» службы RMI. Не стесняйтесь добавлять больше деталей к вопросу, если моя интерпретация здесь неверна, и я попытаюсь ответить на них.
Комментарии:
1. Ну, когда я запускаю свой сервер, веб-сервер показывает мне, что эти 2 класса открыты. Но одного iFund не должно быть. Также, когда клиент получает объект iFund, он пытается использовать его как удаленный объект вместо простой десериализации.
Ответ №2:
Как IStockMarket (как предполагалось), так И iFund (не как предполагалось) становятся удаленными.
Нет, они этого не делают. Объекты «становятся удаленными» только при экспорте, а интерфейсы вообще не «становятся удаленными». Клиенту требуется iFund, предположительно, потому, что он отображается в интерфейсе IStockMarket. Похоже, вы используете функцию codebase. С точки зрения кодовой базы реестр тоже является клиентом. Итак, реестр загружен IFund.class и IStockMarket.class. Это не приводит к тому, что iFund «становится удаленным» каким-либо образом.
Ответ №3:
Хорошо, я нашел это на сайте oracle:http://download.oracle.com/javase/tutorial/rmi/implementing.html .
Веб-сервер публикует мой интерфейс iFund (не удаленный), потому что он передается через метод RMI. Моему клиенту нужен iFund для использования переданного объекта. Я думал, этого было достаточно для работы RMI.
Чего я не знал, так это того, что клиенту ТАКЖЕ необходимо загрузить реализацию класса, чтобы он мог десериализовать объект и использовать методы скопированного объекта. Чтобы это сработало, вы должны использовать securitymanager на стороне клиента. Что очень просто:
if (System.getSecurityManager() == null)
{
System.setSecurityManager(new SecurityManager());
}
Комментарии:
1. Веб-сервер ничего не «публикует». Он возвращает его из вашей кодовой базы, куда вы его поместили, в ответ на запрос GET, выданный клиентом кодовой базы RMI.
2. Это было то, что вы опубликовали файлы, поместив их в кодовую базу. Они требуются там для удовлетворения загрузки класса удаленного интерфейса. Не похоже, что у вас есть какая-либо альтернатива.