2. Реализация
Теперь вы пишете реализацию удаленной службы. Ниже приведен класс CalculatorImpl:
public class CalculatorImpl extends
java.rmi.server. UnicastRemoteObj ect implements Calculator {
// Реализации должны иметь
// явный конструктор для
// того, чтобы объявить
// исключительную ситуацию RemoteException
public CalculatorImpl()
throws java.rmi. RemoteException {
super ();
public long add (long a, long b)
throws java.rmi. RemoteException {return a + b;
public long sub (long a, long b)
throws java.rmi. RemoteException {return a – b;
public long mul (long a, long b)
throws java.rmi. RemoteException {return a * b;
public long div (long a, long b)
throws java.rmi. RemoteException {
return a / b;
}
И опять, скопируйте этот код в ваш каталог и откомпилируйте его.
Класс реализации использует UnicastRemoteOb j ect для присоединения к системе RMI. В данном примере класс реализации непосредственно расширяет UnicastRemoteOb j ect. Это не является обязательным требованием. Класс, не расширяющий UnicastRemoteObj ect, может использовать свой метод exportOb j ect () для присоединения к RMI.
Если класс расширяет UnicastRemoteObj ect, он должен обеспечить конструктор, объявляющий, что он может сгенерировать объект RemoteException. Если этот конструктор вызывает метод super (), он активизирует код в UnicastRemoteObj ect, который выполняет RMI‑соединение и инициализацию удаленного объекта.
3. Заглушки и скелеты
Дальше вы используете компилятор RMI, rmic, для генерации файлов заглушки и скелета. Компилятор запускается с указанием файла класса, реализующего удаленную службу.
>rmic CalculatorImpl
Попробуйте выполнить это в вашем каталоге. После запуска rmic вы должны найти файл Calculator_Stub. class.
4. Хост-сервер
Удаленные службы RMI должны быть помещены в процесс сервера. Класс CalculatorServer является очень простым сервером, предоставляющим простые элементы для размещения.
import java.rmi. Naming;
public class CalculatorServer {
public CalculatorServer () {try {
Calculator c = new CalculatorImpl();
Naming.rebind (»
rmi://localhost:1099/
CalculatorService», c);} catch (Exception e) {
System.out.println («Trouble:» + e);
public static void main (String args[]) {new CalculatorServer();
В этом примере вы видите вызов статического метода Naming.rebind(). Однако этот вызов требует, чтобы регистрация была запущена отдельным процессом на вашем компьютере. Имя сервера регистрации – это rmiregistry, и под 32‑битной Windows вы пишете:
start rmiregistry
для запуска в фоновом режиме.
Как и многие другие сетевые программы, rmiregistry обращается по IP адресу машины, на которой она установлена, но она также слушает порт. Если вы вызовите rmiregistry как показано выше, без аргументов, будет использован порт по умолчанию 1099. Если вы хотите использовать другой порт, вы добавляете аргумент в командную строку, указывающий порт. Следующий пример устанавливает порт 2005, так что rmiregistry под управлением 32-битной Windows должна запускаться так:
start rmiregistry 2005
Информация о порте также должна передаваться в команде bind(), наряду с IP адресом машины, где располагается регистрация. Но это может выявить проблему, если вы хотите проверять RMI программы локально. В выпуске JDK 1.1.1, есть целая связка проблем:
1) localhost не работает с RMI. Поэтому для экспериментов с RMI на одной машине вы должны использовать имя машины. Чтобы найти имя вашей машины под управлением 32‑битной Windows, перейдите в панель управления и выберите «Network». Выберите закладку «Identification», и посмотрите имя вашего компьютера. Регистр в имени игнорируется. (Пример имени: «peppy»)
2) RMI не работает, пока ваш компьютер имеет активные TCP/IP соединения, даже если все ваши компоненты просто общаются друг с другом на локальной машине. Это значит, что вы должны соединятся с вашим провайдером Internet до того, как попробуете запустить программу или будете огорчены неким сообщением об ошибке.
Если учесть все это, команда bind() принимает вид:
Naming.bind (« //peppy:2005/CalculatorService», с);
Если вы используете порт по умолчанию 1099, вам не нужно указывать порт, так что вы можете просто сказать:
Naming.bind (« //peppy/CalculatorService», с);
Вы можете выполнить локальную проверку, оставив в покое IP адрес, а использовать только идентификатор:
Naming.bind («CalculatorService», с);
Имя сервиса здесь произвольно. В данном случае CalculatorService выбрано просто как имя класса, но вы можете назвать так, как захотите. Важно, чтобы это было уникальное имя регистрации, чтобы клиент знал, когда будет искать, что производит удаленные объекты. Если имя уже зарегистрировано, вы получите AlreadyBoundException. Чтобы предотвратить это, вы всегда можете использовать rebind() вместо bind(), так как rebind() либо добавляет новый элемент, либо заменяет уже существующий.
Даже после завершения работы main(), ваш объект будет оставаться созданным и зарегистрированным, ожидая, что придет клиент и выполнит запрос. Пока rmiregistry остается запущенным, и вы не вызовите Naming.unbind() на вашей машине, объект будет оставаться там. По этой причине, когда вы разрабатываете ваш код, вам необходимо выгружать rmiregistry и перезапускать его, когда скомпилируете новую версию вашего удаленного объекта.
Вам не обязательно запускать rmiregistry как внешний процесс. Если вы знаете, что только ваше приложение использует регистрацию, вы можете загрузить ее внутри вашей программы с помощью строки:
LocateRegistry.createRegistry(2005);
Как и раньше, 2005 – это номер порта, который мы использовали в этом примере. Это эквивалентно запуску rmiregistry 2005 из командной строки, но часто этот способ является более подходящим при разработке RMI кода, так как это снжает число необходимых действий при запуске и остановке регистрации После того, как вы выполните этот код, вы можете вызвать bind(), используя Naming, как и ранее.
5. Клиент
Исходный код клиента следующий:
import java.rmi. Naming;•
import java.rmi. RemoteException;
import java.net. MalformedURLException;
import java.rmi. NotBoundException;
public class CalculatorClient {
public static void main (String[] args) {try {
Calculator c = (Calculator)
Naming.lookup («rmi://remotehost
/CalculatorService»); System.out.println (c.sub (4, 3)); System.out.println (c.add (4, 5)); System.out.println (c.mul (3, 6)); System.out.println (c.div (9, 3));
}
catch (MalformedURLException murle) {
System.out.println();
System.out.println (
«MalformedURLException»);
System.out.println(murle);
}
catch (RemoteException re) {
System.out.println();
System.out.println (
«RemoteException»);
System.out.println(re);} catch (NotBoundException nbe) {
System.out.println();
System.out.println (
«NotBoundException»); System.out.println(nbe);
} catch (
java.lang. ArithmeticException
ae) {
System.out.println(); System.out.println (
«java.lang. ArithmeticException»); System.out.println(ae);
6. Запуск RMI‑системы
Теперь вы готовы к запуску системы! Вы должны запустить три консоли, одну для сервера, одну для клиента и одну для реестра RMI.
Начните с реестра. Вы должны находиться в каталоге, в котором находятся написанные вами классы. Напишите следующее:
Rmiregistry
Если не сработает, то в текущем каталоге наберите полный путь к файлу rmiregistry.exe, Он находится в каталоге JAVA_HOME/bin/
Если все пройдет хорошо, реестр начнет работать, и вы можете перейти к следующей консоли.
Во второй консоли запустите сервер, содержащий CalculatorService, и наберите следующее:
>java CalculatorServer
Программа запустится, загрузит реализацию в память и будет ожидать соединения клиента.
В последней консоли запустите клиентскую программу.
>java CalculatorClient
Если все пройдет хорошо, вы увидите следующую информацию:
1
9
18
3
Вот и все: вы создали работающую систему RMI. Даже если вы запустили три консоли на одном и том же компьютере, RMI использует стек протоколов TCP/IP вашей сети для взаимодействия между тремя отдельными JVM. Это вполне законченная RMI‑система.
1. Серия «Библиотека профессионала» К. Хорстманн Г. Корнелл «Java 2. том 2 «Тонкости программирования»» «Издательство Вильямс» 2002 г.
2. Методичка с сайта JGURU.ru
3. Sun Java 2 SE API
... может предоставлять тот или иной сервер приложений. Кроме того, каждый из них должен реализовывать саму спецификацию J2EE, дабы он мог работать с компонентами Enterprise JavaBeans. Для этого в сервере приложений необходим EJB-контейнер, который и отвечает за выполнение компонентов. Компоненты EJB Нередко те, кто малознаком с Enterprise JavaBeans, неверно понимают смысл этих компонентов. Дело в ...
... (расширяемость) драйвера MCI для его настройки на любые аппаратные средства различных изготовителей. Ниже приведена таблица различных устройств мультимедиа и соответствующих им имен на языке MCI: УСТРОЙСТВО MCI-ИМЯ проигыватель компакт-дисков cdaudio цифровой аудиомагнитофон dat цифровое видео ...
0 комментариев