RMI
.pdf{
lm = new LocalModel();
}
//Создание экземпляра
//Remote Interface Wrapper if (null == rmImpl)
{
rmImpl = new RemoteModelImpl (lm);
}
return ((RemoteModelRef) rmImpl);
}
public LocalModel getLocalModel() throws java.rmi.RemoteException
{
//Возвратить ссылку на
//ту же самую LocalModel, //которая существует как delgatee //RMI remote
//object wrapper
//Инсталляция delgatee if (null == lm)
{
lm = new LocalModel();
}
return lm;
}
}
Упражнения
7.Сериализация удаленных объектов: Сервер
8.Сериализация удаленных объектов: Клиент
Архитектуры мобильных агентов
Использование RMI мобильными агентами находится пока еще в стадии разработки. По этой теме были разработаны также другие распределенные архитектуры Java. Они называются архитектурами мобильных клиентов. Например, Aglets Architecture от IBM, или Voyager System от ObjectSpace. Эти системы разработаны специально для разрешения и поддержки перемещения между JVM объектов Java, содержащих свои данные вместе с инструкциями.
Альтернативные реализации
Этот курс рассматривает реализацию архитектуры RMI от Sun. Существуют и другие реализации, например:
•NinjaRMI
Свободно распространяемая реализация, созданная в University of California, Berkeley. Ninja подерживает JDK 1.1 версию RMI с расширениями.
•BEA Weblogic Server
BEA Weblogic Server является высокопроизводительным, безопасным сервером приложений,
поддерживающим RNI, Microsoft COM, CORBA, EJB (Enterprise JavaBeans) и другие службы.
•Voyager
Voyager от ObjectSpace поддерживает RMI вместе с собственной службой DOM, CORBA, EJB, Microsoft DCOM и службы транзакций.
Дополнительные ресурсы
Книги и статьи
•Design Patterns, by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (The Gang of Four)
•Sun's RMI FAQ
•RMI over IIOP
•RMI-USERS Mailing List Archive
•Implementing Callbacks with Java RMI, by Govind Seshadri, Dr. Dobb's Journal, March 1998
Упражнения
Добро пожаловать в раздел «Упражнения jGuru» курса «Основы RMI».
Эти упражнения иллюстрируют использование библиотеки Remote Method Invocation (RMI) для реализации распределенных объектов.
После выполнения упражнений вы узнаете об основных концепциях построения распределенных систем Java, основанных на RMI. Используя эти знания, вы сможете разрабатывать и реализовывать сложные, многомашинные программы Java™.
Содержание упражнений
•Об упражнениях
o Анатомия упражнения
oЦели разработки упражнений
•Упражнения по основам RMI
1.Пример UML-определения системы RMI
2.Простая банковская система
3.Параметры RMI
4.Обратные вызовы RMI-клиента
5.Пример начальной загрузки
6.Распределенная сборка мусора
7.Сериализация удаленных объектов: сервер
8.Сериализация удаленных объектов: клиент
Об упражнениях
Упражнение jGuru является гибким упражнением, обеспечивающим различные уровни помощи, соответствующие требованиям студентов. Некоторые студенты могут выполнить упражнение, используя только информацию и список задач в теле упражнения; некоторые захотят просмотреть несколько советов (Помощь); в то время как остальные захотят использовать пошаговое руководство для успешного выполнения упражнения (Решение). Но так как в дополнение к помощи предоставляется полное решение, они смогут выполнить другие упражнения, зависящие от пропущенных.
Анатомия упражнения
Каждое упражнение включает список требуемых упражнений, скелетный код для начала, ссылки на необходимые страницы API и текстовое описание образовательной цели упражнения. В дополнение, кнопки отсылают вас к следующей информации:
•Помощь: Помощь или советы по текущему упражнению и аннотированное решение. Для простоты использования информация о задаче на странице помощи дублирует фактическую информацию, вставленную ниже ее.
•Решение: Тэг <applet> и исходный код Java приводят к ожидаемому поведению.
•Документация по API: Прямая ссылка на любую необходимую документацию по API.
Цели разработки упражнения
Существуют три фундаментальных типа упражнений, с которыми вы можете столкнуться:
«Чистый экран»
Вы находитесь напротив «чистого экрана» и создаете всю требуемую функциональность полностью самостоятельно.
Расширение
Вы расширяете функциональность существующей, корректно работающей программы.
Восстановление
Вы исправляете нежелательное поведение существующей программы.
Для того чтобы облегчить обучение, упражнения, там где возможно, адресуются только к определенным приемам, для обучения которым и создавалось это упражнение. Несущественные, несвязанные и слишком сложные материалы не используются.
Там где это возможно, упражнения выполняются в Web. Однако упражнения, которые требуют доступа к функциям Java или библиотечным функциям, способным вызвать нарушение безопасности, не выполняются в Web.
Упражнения по основам RMI
1.Пример UML-определения системы RMI
Это упражнение познакомит вас с определением удаленных служб RMI с использованием интерфейсов Java.
Цели обучения:
•Познакомиться с UML-определением банковской системы
•Закончить исходный код Java для системных интерфейсов
2.Простая банковская система
В этом упражнении вы запустите вашу первую RMI-систему. Она основывается на банковской системе, созданной в предыдущем упражнении.
Цели обучения:
•Научиться запускать RMI Registry как отдельный процесс
•Запустить сервер, поддерживающий удаленные объекты RMI
•Реализовать RMI-клиент, использующий удаленные службы
3.Параметры RMI
При вызове удаленного метода удаленному объекту могут быть переданы параметры, а вызывающей программе – возвращаемое значение. В этом упражнении исследуется, как RMI управляет передачей простых типов данных, локальных объектов Java и удаленных объектов RMI в качестве параметров и возвращаемых значений.
Цели обучения:
•Попрактиковаться в определении и реализации удаленных интерфейсов
•Изучить, как удаленные объекты и нормальные объекты передаются в качестве параметров
4.Обратные вызовы RMI-клиента
В некоторых RMI-системах серверу может понадобиться сделать вызов в клиентскую программу. Это может быть сделано при использовании обратных вызовов клиента.
Построить клиентские обратные вызовы с RMI очень легко. Можно просто создать на клиенте удаленный объект и передать ссылку на него серверу. Сервер затем может использовать эту удаленную ссылку для вызова методов в клиентской программе.
Цели обучения:
•Изучить, как создать удаленные объекты на клиенте
•Подготовить и экспортировать удаленные объекты, прямо не расширяющие интерфейс java.rmi.server.UnicastRemoteObject
5.Пример начальной загрузки
Это упражнение содержит три компонента: начальный загрузчик HTTP-сервера, начальный загрузчик RMI-сервера и начальный загрузчик RMI-клиента. Эти компоненты покажут, как RMI поддерживает распределенные, загружаемые по требованию файлы классов посредством FTP и HTTP-серверов.
Сначала вы запустите сервер, который передает файлы классов Java по протоколу HTTP.
Затем вы создадите и запустите начальный загрузчик RMI-сервера. Этот сервер очень похож на другие серверы, которые вы запускали. Главным его отличием в данном упражнении является то, что код RMI-клиента находится в том же каталоге, что и сервер. Передача классов клиента на клиентский компьютер является задачей HTTP-сервера.
И, наконец, вы создадите очень «тонкую» клиентскую программу. Единственной целью этой программы является запуск и затем запрос «реальной» клиентской программы по сети. Запросы для классов Java будут обслуживаться HTTP-сервером, созданным ранее в этом упражнении.
Цели обучения:
•Рассмотреть классы поддержки HTTP-сервера для RMI-системы
•Рассмотреть, как написать простой HTTP-сервер
•Создать и запустить программу RMI-сервера
•Создать программу начальной загрузки клиентской программы по сети
•Запустить начальный загрузчик клиента и рассмотреть, как программа HTTP-сервера сообщает о запрошенных и переданных классах
•Изучить системное свойство java.rmi.server.codebase
6.Распределенная сборка мусора
Распределенный и локальный сборщики мусора работают совместно для управления динамической памятью в каждой Java™ Virtual Machine (JVM), работающей в RMI-системе. В этом упражнении вы будете иметь возможность поэкспериментировать с RMI-сервером и двумя RMI-клиентами для исследования управления динамической памятью.
Цели обучения:
•Исследовать поведение распределенного сборщика мусора
•Исследовать взаимодействие распределенного и локального сборщиков мусора
•Поэкспериментировать с различными установками для кучи Java и отметить, как это влияет на действия двух сборщиков мусора
7.Сериализация удаленных объектов: сервер
Это упражнение показывает, как использовать модель делегирования для создания системы, которая дает возможность сетевым службам мигрировать между локальной JVM и удаленным сервером.
Это простая версия архитектуры делегирования. Более изощренные архитектуры могут быть построены путем расширения этого примера.
Упражнение состоит из двух частей. Сначала запустите сервер, а затем клиент для выполнения примера.
Цели обучения:
•Понять, как RMI ограничивает возможность перемещения удаленных объектов между JVM
•Посмотреть, как использовать модель делегирования для преодоления этих ограничений
8.Сериализация удаленных объектов: клиент
Клиентская программа сделает запрос на обслуживание как удаленной ссылке так и локальной копии объекта.
Цели обучения:
•Увидеть, как создается RMI-клиент, использующий либо удаленную ссылку для обслуживания, либо локальную копию объекта, реализующего эту службу.
Пример UML-определения системы RMI
Это упражнение знакомит вас с определением удаленных служб RMI при помощи интерфейсов Java. Вы будете использовать простую банковскую систему, определенную в следующей UML-диаграмме:
Скелетный код
Account.java
BankManager.java
Client.java
Задачи
1.Исследовать UML-диаграмму для банковской системы
2.Закончить исходный код для определения интерфейсов в этой системе
Там, где существует файл помощи, номера вышеперечисленных задач ссылаются на страницу пошаговой помощи.
После выполнения этого упражнения вы получите определения интерфейсов Java для трех удаленных служб
RMI.
Исходные коды решения
Account.java
BankManager.java
Client.java
Демонстрация
Никакого поведения еще не существует. Это упражнение включает только написание исходного кода.
Помощь
Помощь доступна для каждой задачи.
Задача 1
Исследовать UML-диаграмму для банковской системы.
Вы найдете UML-диаграмму в начале этого упражнения.
Задача 2
Закончить исходный код для определения интерфейсов в этой системе.
Проверьте, что каждый интерфейс расширяет Remote и что каждый метод объявляет, что он может создавать исключительную ситуацию RemoteException.
Простая банковская система
Это упражнение ведет вас к созданию вашей первой RMI-системы.
В этом упражнении вы запустите RMI Registry (который будет управлять публикацией удаленных служб RMI), запустите программу сервера, создающую фактические удаленные службы и, наконец, завершите кодирование программы BankUser, которая будет использовать эти удаленные службы RMI.
Предварительные условия
Пример UML-определения системы RMI
Скелетный код
Account.class
AccountImpl.class
AccountImpl_Stub.class
AccountImpl_Skel.class
BankManager.class
BankManagerImpl.class
BankManagerImpl_Stub.class
BankManagerImpl_Skel.class
Client.class
ClientImpl.class
ClientImpl_Stub.class
ClientImpl_Skel.class
NoCashAvailableException.class
BankSystemServer.class
BankUser.java
Задачи
1.Запустите программу RMI Registry.
2.Скопируйте все .class–файлы в каталог.
3.Запустите RMI-сервер, который содержит удаленные объекты.
4.Создайте и запустите программу, которая будет использовать экспортированные RMI-службы. Найдите владельца счета 4461 и определите сумму денег на этом счету.
Там, где существует файл помощи, номера вышеперечисленных задач ссылаются на страницу пошаговой помощи.
После выполнения упражнения вы получите вашу первую запущенную RMI-систему.
Она состоит из трех основных частей:
•Программа RMI Registry, которая содержит ссылки на удаленные службы.
•Программа RMI-сервера, которая создает удаленные службы, регистрирует их в реестре и ожидает клиентских запросов.
•Программа RMI-клиента, которая получает ссылки на удаленные службы из реестра и затем использует эти службы.
Исходные коды решения
Account.java
Account.class
AccountImpl.java
AccountImpl.class
AccountImpl_Stub.class
AccountImpl_Skel.class
BankManager.java
BankManager.class
BankManagerImpl.java
BankManagerImpl.class
BankManagerImpl_Stub.class
BankManagerImpl_Skel.class
BankUser.java
BankUser.class
Client.java
Client.class
ClientImpl.java
ClientImpl.class
ClientImpl_Stub.class
ClientImpl_Skel.class
NoCashAvailableException.java
NoCashAvailableException.class
BankSystemServer.java
BankSystemServer.class
Демонстрация
Когда запущены RMI Registry и RMI-сервер, нет никаких видимых признаков этого. Когда запущена клиентская программа BankUser, на экране отобразится сообщение, которое вы включили в программу. В данном случае отобразится следующее сообщение: Charlie's account has $600.00
Помощь
Помощь доступна для каждой задачи.
Задача 1
Запустите программу RMI Registry.
Программа RMI Registry поставляется как отдельный исполняемый файл rmiregistry. Создайте консоль и перейдите в каталог, содержащий ваш исходный код из этого упражнения. Запустите реестр, выполнив следующую команду:
rmiregistry
Задача 2
Скопируйте все .class–файлы в каталог.
Нажмите правую кнопку мыши на каждом файле для его сохранения. Исходные файлы предоставлены с решением, на случай, если вы не захотите написать его самостоятельно.
Задача 3
Запустите RMI-сервер, который содержит удаленные объекты.
В этом упражнении сервер и экспортируемые удаленные объекты написаны за вас. Вам нужно просто запустить хост-программу BankSystemServer.
Это осуществляется путем создания новой консоли, переходом в каталог, содержащий код этого упражнения и выполнением следующей команды: java BankSystemServer
Задача 4
Создайте и запустите программу, которая будет использовать экспортированные RMI-службы. Найдите владельца счета 4461 и определите сумму денег на этом счету.
Скелетный код для клиентской программы BankUser предоставляется.
Завершите код для BankUser, используя в качестве ориентиров определения интерфейсов удаленных служб. Затем откомпилируйте и запустите эту программу для проверки RMI-системы в действии.
Параметры RMI
В этом примере вы создадите RMI-службу, возвращающую два объекта клиенту. Как и в упражнении «Простая банковская система» вам необходимо изменить константу HOST_NAME для приведения ее в соответствие с сетевым именем вашего компьютера.
Вы также расширите интерфейс Hello и класс HelloImpl для передачи объекта Java MessageObject из сервера клиенту.
Во время этих изменений обратите особое внимание на MessageObject. Он определяет и переменную класса и переменную объекта, которые инкрементируются каждый раз при создании экземпляра класса. Наблюдая, как эти счетчики инкрементируются на сервере и клиенте, вы можете заметить, что RMI посылает между JVM информацию об экземпляре объекта, а не статическую информацию или информацию уровня класса.
Материалы курса по этому упражнению рассмотрены в разделе «Параметры в RMI».
Предварительные условия
Простая банковская система
Скелетный код
Hello.java
HelloImpl.java
MessageObject.java
RMIServer.java
RMIClient.java
Задачи
1.Добавьте метод getMessageObject в интерфейс Hello
2.Создайте реализацию метода getMessageObject в классе HelloImpl
3.Откомпилируйте все файлы классов для сервера и его удаленных объектов
4.Создайте файлы заглушки и скелета для реализации удаленного объекта
5.Запустите RMI-сервер в отдельной DOS-консоли
6.Запустите RMI-клиент в отдельной DOS-консоли
Там, где существует файл помощи, номера вышеперечисленных задач ссылаются на страницу пошаговой помощи.
Исходные коды решения
Hello.java
HelloImpl.java
MessageObject.java
RMIServer.java
RMIClient.java
Демонстрация
Когда сервер запустится в своей DOS-консоли, отобразится следующая информация:
Registry created on host computer <your_computer_name> on port 10002 Remote HelloService implementation object created Bindings Finished, waiting for client requests.
Затем, когда клиент запустится в своей DOS-консоли, появится следующая информация:
HelloService lookup successful The server says: Hello!
отображая сообщение («Hello»), которое вы определили в реализации объекта.
Так как на вашем компьютере исполняется и сервер и клиент, на экране отображается сообщения из MessageObject. На консоли сервера отображается:
MessageObject: Class Number is #0 Object Number is #0
MessageObject: Class Number is #1 Object Number is #1
MessageObject: Class Number is #2 Object Number is #2
MessageObject: Class Number is #3 Object Number is #3
MessageObject: Class Number is #4 Object Number is #4
MessageObject: Class Number is #5 Object Number is #5
MessageObject: Class Number is #6 Object Number is #6
MessageObject: Class Number is #7 Object Number is #7
MessageObject: Class Number is #8 Object Number is #8
MessageObject: Class Number is #9 Object Number is #9
На консоли клиента отображается:
MessageObject: Class Number is #0 Object Number is #0
MessageObject: Class Number is #0 Object Number is #1
MessageObject: Class Number is #0 Object Number is #2
MessageObject: Class Number is #0 Object Number is #3
MessageObject: Class Number is #0 Object Number is #4
MessageObject: Class Number is #0 Object Number is #5
MessageObject: Class Number is #0 Object Number is #6
MessageObject: Class Number is #0 Object Number is #7
MessageObject: Class Number is #0 Object Number is #8
MessageObject: Class Number is #0 Object Number is #9
Обратите внимание на различие в номерах класса.
Когда экземпляр MessageObject перемещается между сервером и клиентом, две JVM загружают свои собственные независимые копии файла класса. Переменная класса инкрементируется на сервере, но это никак не отражается на клиенте.
Помощь
Помощь доступна для каждой задачи.
Задача 1
Добавьте метод getMessageObject в интерфейс Hello.
В файле Hello.java добавьте следующий метод для определения интерфейса: MessageObject getMessageObject() throws RemoteException;
Задача 2
Создайте реализацию метода getMessageObject в классе HelloImpl.
Добавьте удаленный метод getMessageObject и возвратите новый экземпляр класса
MessageObject.
Вы можете использовать следующий код:
public MessageObject getMessageObject() throws RemoteException
{
return new MessageObject();
}
Задача 3
Откомпилируйте все файлы классов для сервера и его удаленных объектов.
Используйте программу javac:
javac *.java