Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

RMI

.pdf
Скачиваний:
32
Добавлен:
30.05.2015
Размер:
1.14 Mб
Скачать

Задача 4

Создайте файлы заглушки и скелета для реализации удаленного объекта.

Используйте программу rmic с классом реализации HelloImpl.

rmic HelloImpl

Задача 5

Запустите RMI-сервер в отдельной DOS-консоли.

Запустите новую DOS-консоль. Перейдите из текущего каталога в каталог, содержащий ваши .javaфайлы для сервера. Запустите RMIServer, используя программу java:

java RMIServer

Задача 6

Запустите RMI-клиент в отдельной DOS-консоли.

Запустите новую DOS-консоль. Перейдите из текущего каталога в каталог, содержащий ваши .javaфайлы для клиента. Запустите RMIClient, используя программу java:

java RMIClient

Обратные вызовы RMI-клиента

В этом упражнении вы создадите клиентский апплет, который будет работать и как RMI-клиент, и как RMIсервер. Обычно апплеты работают только как клиенты, однако в некоторых случаях серверу может понадобиться сделать обратный вызов в апплет. В этом упражнении сервер будет периодически вызывать апплет и передавать ему текущую дату и время.

Для поддержки обратных вызовов, апплет должен действовать как RMI-сервер. Это осуществляется при помощи экспорта и реализации удаленного интерфейса. Наш апплет определяет и реализует интерфейс TimeMonitor. Он предназначен для вызова службой времени, обеспечивающей текущую дату и время.

Сервер не может сделать обратный вызов в апплет до тех пор, пока не узнает его расположение. Апплет должен зарегистрировать себя на сервере. Он делает это при помощи метода сервера registerTimeMonitor в TimeServer и передает ссылку на себя в интерфейс сервера.

В этом упражнении вам необходимо определить интерфейсы и реализации как для сервера, так и для апплета.

Предварительные условия

Клиентские обратные вызовы RMI

Скелетный код

TimeMonitor.java

TimeServer.java

RMIServer.java

Applet1.java

Задачи

1.Определите и откомпилируйте интерфейс TimeMonitor

2.Определите и откомпилируйте интерфейс TimeServer

3.Закончите реализацию метода registerTimeMonitor в RMIServer

4.Закончите определение класса TimeTicker

5.Откомпилируйте сервер, RMIServer и создайте файлы заглушки и скелета

6.Подготовьте апплет для исполнения

7.Запустите RMI-сервер в отдельной DOS-консоли

8.Запустите апплет при помощи appletviewer

Там, где существует файл помощи, номера вышеперечисленных задач ссылаются на страницу пошаговой помощи.

Исходные коды решения

TimeMonitor.java

TimeServer.java

RMIServer.java

Applet1.java

Демонстрация

Когда сервер запускается в DOS-консоли, отображается следующая информация:

Registry created

Bindings Finished

Waiting for Client requests

Когда апплет запускается в своей DOS-консоли, отображается следующая информация:

Exporting the Applet Looking up TimeService at:

rmi://<your_computer_name>:10005/TimeServer We have been registered!

Апплет появится в окне и начнет отображать текущую дату и время каждые две секунды.

Помощь

Помощь доступна для каждой задачи.

Задача 1

Определите и откомпилируйте интерфейс TimeMonitor.

Создайте интерфейс TimeMonitor, имеющий один метод. Этот метод называется tellMeTheTime. Он принимает один параметр типа Date и возвращает void.

Помните, что удаленные интерфейсы должны расширять java.rmi.Remote и все удаленные методы могут генерировать java.rmi.RemoteException.

Откомпилируйте файл при помощи следующей команды:

javac TimeMonitor.java

Задача 2

Определите и откомпилируйте интерфейс TimeServer.

Создайте интерфейс TimeServer, имеющий один метод. Этот метод называется registerTimeMonitor. Он принимает один параметр типа TimeMonitor и возвращает void.

Помните, что удаленные интерфейсы должны расширять java.rmi.Remote и все удаленные методы могут генерировать java.rmi.RemoteException.

Откомпилируйте файл при помощи следующей команды: javac TimerServer.java

Задача 3

Закончите реализацию метода registerTimeMonitor в RMIServer.

Класс RMIServer реализует интерфейс TimeServer. Вам необходимо откомпилировать реализацию registerTimeMonitor в RMIServer. Обратитесь к комментариям в исходном файле за подробной информацией.

Задача 4

Закончите определение класса TimeTicker.

Класс TimeTicker определяется внутри файла для RMIServer. Вам необходимо откомпилировать реализацию этого класса, после добавления вызова метода tellMeTheTime интерфейса TimeMonitor. В этом методе выполняется обратный вызов в апплет.

Задача 5

Откомпилируйте сервер, RMIServer и создайте файлы заглушки и скелета.

Используйте программу javac для компиляции файла RMIServer:

javac RMIServer

Используйте программу rmic с RMIServer.

rmic RMIServer

Обратите внимание, что RMIServer реализует экспортируемую службу. Поскольку RMIServer расширяет RMIServer, он не может также расширить UnicastRemoteObject. Вместо этого

RMIServer должен сделать явный вызов UnicastRemoteObject.exportObject перед тем, как он сможет зарегистрировать себя в реестре. Этот вызов обычно делается автоматически в конструкторе объекта UnicastRemoteObject.

Задача 6

Подготовьте апплет для исполнения.

Код апплета написан за вас. Вы должны исследовать его, чтобы понять, как реализуется интерфейс TimeMonitor и как он подготавливает себя для использования в RMI с помощью вызова

UnicastRemoteObject.exportObject.

Прежде всего, вам необходимо откомпилировать его при помощи следующей команды:

javac Applet1.java

Далее, создайте файлы заглушки и скелета, используя программу rmic:

rmic Applet1

Задача 7

Запустите RMI-сервер в отдельной DOS-консоли.

Запустите класс RMIServer, используя програму java.

java RMIServer

Задача 8

Запустите апплет при помощи appletviewer.

Используйте программу appletviewer и выполните файл Applet.html. Этот HTML-файл содержит команды для запуска Applet1.class.

appletviewer Applet.html

Пример начальной загрузки

Это упражнение содержит три компонента: начальный загрузчик HTTP-сервера, начальный загрузчик RMIсервера и начальный загрузчик RMI-клиента. Эти компоненты покажут, как RMI поддерживает распределенные, загружаемые по требованию файлы классов посредством FTP и HTTP-серверов. Сначала вы запустите простой, «легковесный» HTTP-сервер. Он работает как сетевой сервер для файлов классов, которые требуются для RMI-клиента и RMI-сервера.

HTTP-сервер реализуется двумя классами, предоставленными Sun Microsystems. Файл ClassLoader.java является абстрактным классом, а файл ClassFileLoader.java является классом реализации для HTTP-сервера. Этот сервер очень простой и служит только для передачи файлов классов

Java.

Вы должны поместить файлы HTTP-сервера в подкаталог, отличный от каталога, содержащего файлы RMIсервера и клиента. После компиляции запустите HTTP-сервер из своего подкаталога и добавьте параметр пути, который укажет HTTP-серверу переместить файлы классов из подкаталога RMI-сервера.

Затем вы создадите и запустите начальный загрузчик RMI-сервера. Этот сервер очень похож на другие серверы, которые вы запускали. Главным его отличием в данном упражнении является то, что код RMIклиента находится в том же каталоге, что и код сервера. Обратите внимание, что все файлы уже созданы за вас. Передача классов клиента на клиентский компьютер является задачей HTTP-сервера.

И, наконец, вы создадите RMI-программу начальной загрузки RMIClientLoader.java. Проверьте, что этот файл расположен в отдельном каталоге, отличном от каталогов, содержащих файлы HTTP-сервера и файлы RMI-клиента и RMI-сервера. Единственной целью этой программы является запуск и затем запрос «реальной» клиентской программы по сети. Запросы для классов Java будут обслуживаться HTTP-сервером, созданным ранее в этом упражнении.

Одной из проблем создания загрузочной программы является передача начальной информации из нее в фактический код клиента. Программа использует системное свойство для сохранения информации, которая должна быть передана в фактическую клиентскую программу.

Обратите внимание, что в этом упражнении важно запускать программы в следующей последовательности:

1.Начальный загрузчик HTTP-сервера

2.Начальный загрузчик RMI-сервера

3.Начальный загрузчик RMI-клиента

Это упражнение является примером модели распространения классов, называемой «Начальная загрузка». Эта модель рассматривается в разделе «Автоматическое распространение классов» данного курса.

Скелетный код

ClassServer.java ClassFileServer.java runhttp.bat MessageObject.java Hello.java RMIServer.java HelloImpl.java runserver.bat RMIClient.java

RMIClientBootstrapSecurityManager.java RMIClientLoader.java

runclient.bat

Задачи

1.Сохраните два файла программы и командный файл runhttp.bat в какой-нибудь каталог и откомпилируйте файлы HTTP-сервера

2.Запустите HTTP-сервер

3.Откомпилируйте все файлы классов для клиента и сервера

4.Создайте файлы заглушки и скелета для реализации удаленного объекта

5.Запустите программу RMI-сервера

6.Откомпилируйте файлы классов для программы начальной загрузки

7.Отредактируйте командный файл runclient.bat, включив имя вашего компьютера

8.Запустите командный файл runclient.bat

Там, где существует файл помощи, номера вышеперечисленных задач ссылаются на страницу пошаговой помощи.

Исходные коды решения

ClassServer.java ClassFileServer.java runhttp.bat MessageObject.java Hello.java RMIServer.java HelloImpl.java runserver.bat RMIClient.java

RMIClientBootstrapSecurityManager.java RMIClientLoader.java

runclient.bat

Демонстрация

Когда HTTP-сервер запускается в DOS-консоли, отображается следующая информация:

ClassFileServer started...

Когда клиент запускается и загружает файлы из HTTP-сервера, обратите внимание, что HTTP-сервер отображает файлы, которые он читает с диска. Первая программа, которую он передает, представляет собой собственно клиентскую программу RMIClient. После этого, он передает файлы заглушки и другие файлы классов, необходимые для работы клиента.

Когда RMI-сервер запускается в DOS-консоли, отображается следующая информация:

Registry created on host computer localhost on port 10009

Remote Hello implementation object created

Bindings Finished, waiting for client requests.

Наконец, когда клиентская программа начальной загрузки выполняется в своей консоли, отображается следующая информация:

http://ROSA:2002/

After loading Client Class

Message from Server: Hello!

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

В то же время вы можете заметить, что в консоли RMI-сервера отображается:

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

Помощь

Помощь доступна для каждой задачи.

Задача 1

Сохраните два файла программы и командный файл runhttp.bat в какой-нибудь каталог и откомпилируйте файлы HTTP-сервера.

Используйте программу javac для компиляции всех файлов Java:

javac ClassServer.java javac ClassFileServer.java

Задача 2

Запустите HTTP-сервер

Создайте новое консольное окно и перейдите в каталог, содержащий откомпилированные классы. Когда вы запускаете HTTP-сервер, вы передаете ему два параметра. Первый – это номер порта, который он прослушивает. Второй – это путь к каталогу, содержащему файлы классов RMI, предназначенные для передачи по сети.

Используйте следующую команду для запуска HTTP-сервера:

java ClassFileServer 2002 <path to class file directory>

В предоставленном пакетном файле runhttp.bat перед его запуском требуется изменить соответствующий путь.

Задача 3

Откомпилируйте все файлы классов для клиента и сервера

В отдельном консольном окне сохраните файлы клиента и сервера в отдельном подкаталоге и откомпилируйте все исходные .java–файлы:

javac MessageObject.java javac Hello.java

javac RMIServer.java javac HelloImpl.java javac RMIClient.java

Таким образом компилируется сервер и все классы клиента, которые впоследствии будут загружаться начальным загрузчиком по сети.

Задача 4

Создайте файлы заглушки и скелета для реализации удаленного объекта

Используйте программу rmic с классом реализации HelloImpl.

rmic HelloImpl

Задача 5

Запустите программу RMI-сервера

Командный (пакетный) файл runserver.bat создан для того, чтобы помочь вам запустить RMIсервер. Отредактируйте этот файл и запишите в него корректную информацию для вашего компьютера, а затем запустите сервер в отдельном консольном окне.

Задача 6

Откомпилируйте файлы классов для программы начальной загрузки

В отдельном консольном окне сохраните файлы клиентской программы начальной загрузки и запустите командный файл runclient.bat в отдельном подкаталоге, скомпилируйте исходные .java-файлы:

javac RMIClientBootstrapSecurityManager.java javac RMIServer.java

Единственной целью программы начальной загрузки является запуск и затем запрос «реальной» клиентской программы по сети.

Задача 7

Отредактируйте командный файл runclient.bat, включив имя вашего компьютера

Измените имя «ROSA» на имя вашего компьютера. Командный файл будет готов к запуску.

Задача 8

Запустите командный файл runclient.bat.

Распределенная сборка мусора

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

Вэтом упражнении не требуется писать код, но вы должны изменить значение константы HOST_NAME на соответствующее имя вашего компьютера. Вам также следует посмотреть на код классов этого примера, особенно MessageObjectImpl, для того, чтобы понять, как он работает.

Упражнение содержит два удаленных объекта: Hello и MessageObject. Их реализации разработаны для того, чтобы вывести сообщения при их создании, удалении ссылок на них, финализации и уничтожении.

Удаленный объект может реализовать интерфейс Unreferenced и его метод unreferenced. Этот метод вызывается DGC во время удаления им последней ссылки на объект. MessageObjectImpl и HelloImpl разработаны так, что выводят сообщение об этой ситуации.

MessageObjectImpl и HelloImpl также реализуют метод finalize. Он вызывается тогда, когда локальный сборщик мусора собирается уничтожить объект и освободить занимаемую им память. В этой реализации MessageObjectImpl и HelloImpl отображают сообщение об этом.

Материалы курса для этого упражнения рассмотрены в разделе «Распределенный сборщик мусора».

Для выполнения упражнения, запустите RMIServer и две копии клиента RMIClient.

При запуске упражнения вы, возможно, захотите поэкспериментировать с установками размера кучи Java (используйте аргумент командной строки – mx) и явно установить значение leaseValue для удаленных ссылок DGC. Для этого используйте следующую командную строку:

java -Djava.rmi.dgc.leaseValue=10000 RMIServer

где время для leaseValue указывается в миллисекундах.

Скелетный код

Hello.java

HelloImpl.java

MessageObject.java

MessageObjectImpl.java

RMIServer.java

RMIClient.java

Задачи

1.Измените значение константы HOST_NAME в RMIClient.java и RMIServer.java на соответствующее имя вашего компьютера

2.Откомпилируйте все исходные Java-файлы

3.Из подкаталога Solution запустите сервер RMIServer с наименьшим возможным размером кучи

4.Запустите два экземпляра клиента

Там, где существует файл помощи, номера вышеперечисленных задач ссылаются на страницу пошаговой помощи.

Исходные коды решения

Hello.java

HelloImpl.java

MessageObject.java

MessageObjectImpl.java

RMIServer.java

RMIClient.java

Демонстрация

Когда сервер запускается в DOS-консоли, отображается следующая информация:

Registry created on host computer ROSA on port 10007 Remote HelloService implementation object created Bindings Finished, waiting for client requests.

Когда клиент запускается в DOS-консоли, отображается следующая информация:

HelloService lookup successful Message from Server: Hello!

При работе двух клиентов в каждой DOS-консоли будут отображаться сообщения.

На консоли сервера будет отображаться следующая информация:

MessageObject: Class Number is #1882 Object Number is #1882 MessageObject: Unreferenced for object #: 1841 MessageObject: Finalize for object #: 893

На каждой из клиентских консолей будет отображаться примерно следующее:

MessageObject: Class Number is #1882 Object Number is #1882

Исследуйте, как консоль сервера отображает процесс работы GDC и локального сборщика мусора.

Помощь

Помощь доступна для каждой задачи.

Задача 1

Измените значение константы HOST_NAME в RMIClient.java и RMIServer.java на соответствующее имя вашего компьютера.

Задача 2

Откомпилируйте все исходные Java-файлы.

Используйте программу javac:

javac *.java

Задача 3

Из подкаталога Solution запустите сервер RMIServer с наименьшим возможным размером кучи.

Запустите новую DOS-консоль и перейдите в каталог, содержащий java-код.

Выполните следующую команду: java -mx1m RMIServer Она запустит Java Virtual Machine с кучей, которая не может расти.

Задача 4

Запустите два экземпляра клиента.

Запустите две дополнительные DOS-консоли и перейдите в каталог с Java-кодом. В каждой DOS-консоли подготовьтесь выполнить команду:

java RMIClient

но не нажимайте пока клавишу «Enter».

Когда готовы обе консоли, нажмите клавишу «Enter» в обеих, так чтобы запустить программу примерно в одно и то же время.

Обратите внимание на отображаемую в различных консолях информацию. Сервер будет показывать, когда он создает каждый объект. Когда каждый объект MessageObject теряет ссылку, сервер будет выводить сообщение; также будет выводиться сообщение при уничтожении каждого MessageObject локальным сборщиком мусора.

Заметьте, что локальный сборщик мусора не уничтожает объекты сразу, как только они закончили свою работу. Вы также можете заметить, что после завершения демонстрации сервер полностью освобождает все объекты примерно через 10 минут. Это указывает на то, что срок аренды этих удаленных объектов был установлен в значение 10 минут. Так как клиенты завершили свою работу, сервер будет ждать окончания срока аренды перед переводом объектов в состояние «чистый».

Сериализация удаленных объектов: сервер

Вэтом упражнении вы запустите серверную часть демонстрации RMI. Все файлы созданы за вас.

Вэтом упражнении вы увидите, как используется модель делегирования для разрешения миграции службы. Эта тема описана в разделе «Cериализация удаленных объектов».

Скелетный код

RemoteModelMgr.java

RemoteModelMgrImpl.java

RemoteModelImpl.java

LocalRemoteServer.java

LocalModel.java

RemoteModelRef.java

Задачи

1.Откомпилируйте все файлы классов сервера

2.Создайте файлы заглушки и скелета для реализации удаленного объекта

3.Запустите программу RMI-сервера

Там, где существует файл помощи, номера вышеперечисленных задач ссылаются на страницу пошаговой помощи.

После окончания этого упражнения перейдите к следующему для выполнения данного проекта.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]