Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

Начинающий Используя RMI Java™

Это учебное руководство показывает Вам шаги, чтобы следовать, чтобы создать распределенную версию классики Привет Мировая программа, используя Java™ Удаленный Вызов метода (Java RMI). В то время как Вы работаете через этот пример, Вы, вероятно, придумаете много связанных вопросов. Вы поощряетесь искать ответы в Java FAQ RMI и архивы списка рассылки ПОЛЬЗОВАТЕЛЕЙ RMI. Если требуется подписаться на список рассылки ПОЛЬЗОВАТЕЛЕЙ RMI, щелкните здесь.

Распределенный Привет Мировой пример использует простой клиент, чтобы сделать удаленный вызов метода к серверу, который может работать на удаленном узле. Клиент получает "Привет, мир!" сообщение от сервера.

У этого учебного руководства есть следующие шаги:

Файлы, необходимые для этого учебного руководства: Отметьте: Для остатка от этого учебного руководства термины "реализация удаленного объекта" и "класс реализации" используются взаимозаменяемо, чтобы обратиться к классу example.hello.Server, который реализует удаленный интерфейс.

Определите удаленный интерфейс

Удаленный объект является экземпляром класса, который реализует удаленный интерфейс. Удаленный интерфейс расширяет интерфейс java.rmi.Remote и объявляет ряд удаленных методов. Каждый удаленный метод должен объявить java.rmi.RemoteException (или суперкласс RemoteException) в throws пункт, в дополнение к любым специализированным исключениям.

Вот интерфейсное определение для удаленного интерфейса, используемого в этом примере, example.hello.Hello. Это объявляет только один метод, sayHello, который возвращает строку вызывающей стороне:

package example.hello;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Hello extends Remote {
    String sayHello() throws RemoteException;
}
Удаленные вызовы метода могут перестать работать многими дополнительными способами по сравнению с локальными вызовами метода (такими как связанные с сетью проблемы коммуникации и проблемы сервера), и отдалить методы, сообщат такие отказы, бросая a java.rmi.RemoteException. Для получения дополнительной информации о проблемах отказа и восстановления в распределенных системах, см. Примечание по Распределенным вычислениям.

Реализуйте сервер

Класс "сервера", в этом контексте, является классом, у которого есть a main метод, который создает экземпляр реализации удаленного объекта, экспортирует удаленный объект, и затем связывает тот экземпляр с именем в Java реестр RMI. Класс, который содержит это main метод мог быть классом реализации непосредственно, или другим классом полностью.

В этом примере, main метод для сервера определяется в классе Server который также реализует удаленный интерфейс Hello. Сервер main метод делает следующее:

Вот исходный код для класса Server. Описания для того, чтобы записать этот класс сервера следуют за исходным кодом:
package example.hello;
        
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
        
public class Server implements Hello {
        
    public Server() {}

    public String sayHello() {
        return "Hello, world!";
    }
        
    public static void main(String args[]) {
        
        try {
            Server obj = new Server();
            Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

            // Bind the remote object's stub in the registry
            Registry registry = LocateRegistry.getRegistry();
            registry.bind("Hello", stub);

            System.err.println("Server ready");
        } catch (Exception e) {
            System.err.println("Server exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

Класс реализации Server реализует удаленный интерфейс Hello, обеспечение реализации для удаленного метода sayHello. Метод sayHello не должен объявить, что это выдает любое исключение, потому что реализация самого метода не бросает RemoteException и при этом это не выдает никакие другие проверенные исключения.

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

Создайте и экспортируйте удаленный объект

main метод сервера должен создать удаленный объект, который предоставляет услугу. Дополнительно, удаленный объект должен быть экспортирован в Java время выполнения RMI так, чтобы это могло получить входящие удаленные вызовы. Это может быть сделано следующим образом:
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

Статический метод UnicastRemoteObject.exportObject экспортирует предоставленный удаленный объект, чтобы получить входящие удаленные вызовы метода на анонимном порту TCP и возвращает тупик для удаленного объекта, чтобы передать клиентам. В результате exportObject вызовите, время выполнения может начать слушать на новом сокете сервера или может использовать совместно используемый сокет сервера, чтобы принять входящие удаленные призывы к удаленному объекту. Возвращенный тупик реализует тот же самый набор удаленных интерфейсов как класс удаленного объекта и содержит имя хоста и порт, по которому можно связаться с удаленным объектом.

Отметьте: С J2SE 5.0 выпусков тупиковые классы для удаленных объектов больше не должны быть предварительно сгенерированы, используя rmic тупиковый компилятор, если удаленный объект не должен поддерживать клиенты, работающие в пред5.0 VMs. Если Ваше приложение должно поддерживать такие клиенты, Вы должны будете генерировать тупиковые классы для удаленных объектов, используемых в приложении, и развернуть те тупиковые классы для клиентов, чтобы загрузить. Для получения дополнительной информации на том, как генерировать тупиковые классы, см. документацию инструментов для rmic [Солярис, Windows]. Для получения дополнительной информации на том, как развернуть Ваше приложение наряду с предварительно сгенерированными тупиковыми классами, см. учебное руководство по кодовой базе.

Зарегистрируйте удаленный объект в Java реестр RMI

Для вызывающей стороны (клиент, коллега, или апплет), чтобы быть в состоянии вызвать метод на удаленный объект, та вызывающая сторона должна сначала получить тупик для удаленного объекта. Для начальной загрузки Java RMI обеспечивает API реестра для приложений, чтобы обязать имя к тупику удаленного объекта и для клиентов искать удаленные объекты по имени, чтобы получить их тупики.

Реестр RMI Java является упрощенной службой имен, которая позволяет клиентам получать ссылку (тупик) к удаленному объекту. Вообще, реестр используется (если вообще) только, чтобы определить местоположение первого удаленного объекта, который должен использовать клиент. Затем, обычно, тот первый объект поочередно оказал бы специализированную поддержку для того, чтобы найти другие объекты. Например, ссылка может быть получена в качестве параметра к, или возвращаемое значение от, другой удаленный вызов метода. Для обсуждения на том, как это работает, пожалуйста смотрите на Применение Шаблона "фабрика" к Java RMI.

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

Следующий код в сервере получает тупик для реестра на локальном узле и порту реестра по умолчанию и затем использует тупик реестра, чтобы связать имя "Привет" к тупику удаленного объекта в том реестре:

Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);
Статический метод LocateRegistry.getRegistry это не берет возвратов параметров тупик, который реализует удаленный интерфейс java.rmi.registry.Registry и отправляет вызовы реестру на локальном узле сервера на порту реестра по умолчанию 1099. bind метод тогда вызывается на registry тупик, чтобы связать тупик удаленного объекта с именем"Hello" в реестре.

Отметьте: звонок LocateRegistry.getRegistry просто возвращает соответствующий тупик для реестра. Вызов не проверяет, чтобы видеть, работает ли реестр фактически. Если никакой реестр не работает на порту TCP 1099 из локального узла когда bind метод вызывается, сервер перестанет работать с a RemoteException.

Реализуйте клиент

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

Вот исходный код для клиента:

package example.hello;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

    private Client() {}

    public static void main(String[] args) {

        String host = (args.length < 1) ? null : args[0];
        try {
            Registry registry = LocateRegistry.getRegistry(host);
            Hello stub = (Hello) registry.lookup("Hello");
            String response = stub.sayHello();
            System.out.println("response: " + response);
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

Этот клиент сначала получает тупик для реестра, вызывая помехи LocateRegistry.getRegistry метод с именем хоста, определенным на командной строке. Если никакое имя хоста не определяется, то null используется в качестве имени хоста, указывающего, что локальный адрес узла должен использоваться.

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

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

Сообщение ответа, возвращенное из удаленного вызова на удаленном объекте, тогда печатается к System.out.

Скомпилируйте исходные файлы

Исходные файлы для этого примера могут быть скомпилированы следующим образом:

javac -d destDir Hello.java Server.java Client.java
где destDir является целевым каталогом, чтобы вставить файлы класса.

Отметьте: Если сервер должен поддерживать клиенты, работающие на пред5.0 VMs, то тупиковый класс для класса реализации удаленного объекта должен быть предварительно сгенерирован, используя rmic компилятор, и что тупиковый класс должен быть сделан доступным для клиентов, чтобы загрузить. См. учебное руководство по кодовой базе для большего количества деталей.

Запустите Java реестр RMI, сервер, и клиент

Чтобы выполнить этот пример, Вы должны будете сделать следующее:

Запустите Java реестр RMI

Чтобы запустить реестр, работайте rmiregistry команда на узле сервера. Эта команда не производит вывода (когда успешный), и обычно выполняется в фоновом режиме. Для получения дополнительной информации см. документацию инструментов для rmiregistry [Солярис, Windows].

Например, на Солярисе (ТМ) Операционная система:

rmiregistry &

Или, на платформах Windows:

start rmiregistry 

По умолчанию реестр работает на порту TCP 1099. Чтобы запустить реестр на различном порту, определите номер порта из командной строки. Например, чтобы запустить реестр на порту 2001 на платформе Windows:

start rmiregistry 2001

Если реестр будет работать на порту кроме 1099, Вы должны будете определить номер порта в звонках LocateRegistry.getRegistry в Server и Client классы. Например, если реестр работает на порту 2001 в этом примере, звонке getRegistry в сервере был бы:

Registry registry = LocateRegistry.getRegistry(2001);

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

Чтобы запустить сервер, работайте Server класс используя java команда следующим образом:

На Операционной системе Соляриса:

java -classpath classDir -Djava.rmi.server.codebase=file:classDir/ example.hello.Server &

На платформах Windows:

start java -classpath classDir -Djava.rmi.server.codebase=file:classDir/ example.hello.Server

где classDir является корневым каталогом дерева файла класса (см. destDir в разделе "Компиляция исходных файлов"). Установка java.rmi.server.codebase системное свойство гарантирует, что реестр может загрузиться, удаленное интерфейсное определение (отметьте, что запаздывающая наклонная черта важна); для получения дополнительной информации об использовании этого свойства, см. учебное руководство по кодовой базе.

Вывод от сервера должен быть похожим на это:

Server ready

Сервер остается работать, пока процесс не завершается пользователем (обычно, уничтожая процесс).

Выполните клиент

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

java  -classpath classDir example.hello.Client

где classDir является корневым каталогом дерева файла класса (см. destDir в разделе "Компиляция исходных файлов").

Вывод от клиента является следующим сообщением:

response: Hello, world!


Oracle и/или его филиалы Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами