Spec-Zone .ru
спецификации, руководства, описания, API
След: RMI
Раздел: Запись Сервера RMI
Реализация Удаленного Интерфейса
Домашняя страница > RMI

Реализация Удаленного Интерфейса

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

Программа сервера RMI должна создать начальные удаленные объекты и экспортировать их во время выполнения RMI, которое делает их доступными, чтобы получить входящие удаленные вызовы. Эта процедура установки может или инкапсулироваться в методе реализации удаленного объекта class непосредственно или включена в другой class полностью. Процедура установки должна сделать следующее:

Полная реализация вычислить механизма следует. engine.ComputeEngine class реализует удаленный интерфейс Compute и также включает main метод для того, чтобы установить вычислить механизм. Вот исходный код для ComputeEngine class:

package engine;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import compute.Compute;
import compute.Task;

public class ComputeEngine implements Compute {

    public ComputeEngine() {
        super();
    }

    public <T> T executeTask(Task<T> t) {
        return t.execute();
    }

    public static void main(String[] args) {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
        try {
            String name = "Compute";
            Compute engine = new ComputeEngine();
            Compute stub =
                (Compute) UnicastRemoteObject.exportObject(engine, 0);
            Registry registry = LocateRegistry.getRegistry();
            registry.rebind(name, stub);
            System.out.println("ComputeEngine bound");
        } catch (Exception e) {
            System.err.println("ComputeEngine exception:");
            e.printStackTrace();
        }
    }
}

Следующие разделы обсуждают каждый компонент вычислить реализации механизма.

Объявление Удаленных Реализовываемых Интерфейсов

Реализация class для вычислить механизма объявляется следующим образом:

public class ComputeEngine implements Compute

Это объявление утверждает, что class реализует Compute отдалите интерфейс, и поэтому может использоваться для удаленного объекта.

ComputeEngine class определяет реализацию удаленного объекта class, который реализует единственный удаленный интерфейс и никакие другие интерфейсы. ComputeEngine class также содержит два элемента исполняемой программы, которые могут только быть вызваны локально. Первым из этих элементов является конструктор для ComputeEngine экземпляры. Вторым из этих элементов является a main метод, который используется, чтобы создать a ComputeEngine экземпляр и делает это доступным для клиентов.

Определение Конструктора для Удаленного объекта

ComputeEngine У class есть единственный конструктор, который не берет параметров. Код для конструктора следующие:

public ComputeEngine() {
    super();
}

Этот конструктор только вызывает конструктора суперкласса, который является конструктором без параметров Object class. Хотя конструктор суперкласса вызывается даже если опущенный от ComputeEngine конструктор, это включается для ясности.

Обеспечение Реализаций для Каждого Удаленного Метода

class для удаленного объекта обеспечивает реализации для каждого удаленного метода, определенного в удаленных интерфейсах. Compute интерфейс содержит единственный удаленный метод, executeTask, который реализуется следующим образом:

public <T> T executeTask(Task<T> t) {
    return t.execute();
}

Этот метод реализует протокол между ComputeEngine удаленный объект и его клиенты. Каждый клиент обеспечивает ComputeEngine с a Task объект, у которого есть определенная реализация Task интерфейс execute метод. ComputeEngine выполняет задачу каждого клиента и возвращает результат задачи execute метод непосредственно клиенту.

Передача Объектов в RMI

Параметры или возвращаемые значения от удаленных методов могут иметь почти любой тип, включая локальные объекты, удаленные объекты, и примитивные типы данных. Более точно к любому объекту любого типа можно передать или от удаленного метода, пока объект является экземпляром типа, который является примитивным типом данных, удаленным объектом, или сериализуемым объектом, что означает, что это реализует интерфейс java.io.Serializable.

Некоторые объектные типы не соответствуют ни одному из этих критериев и таким образом не могут быть переданы к или возвращены из удаленного метода. Большинство этих объектов, таких как потоки или дескрипторы файлов, инкапсулирует информацию, которая имеет смысл только в пределах единственного адресного пространства. Многие из базовых классов, включая классы в пакетах java.lang и java.util, реализуйте Serializable интерфейс.

Управление правил, как параметры и возвращаемые значения передают, следующие:

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

Например, если Вы должны были передать ссылку на экземпляр ComputeEngine class, у получателя был бы доступ только к вычислить механизму executeTask метод. Тот получатель не видел бы ComputeEngine конструктор, main метод, или его реализация любых методов java.lang.Object.

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

Реализация Сервера main Метод

Самый сложный метод ComputeEngine реализация main метод. main метод используется, чтобы запуститься ComputeEngine и поэтому потребности сделать необходимую инициализацию и обслуживание, чтобы подготовить сервер, чтобы принять вызовы от клиентов. Этот метод не является удаленным методом, что означает, что он не может быть вызван от различной виртуальной машины Java. Поскольку main метод объявляется static, метод не связывается с объектом вообще, а скорее с class ComputeEngine.

Создание и Установка Менеджера безопасности

main первая задача метода состоит в том, чтобы создать и установить менеджера безопасности, который защищает доступ к системным ресурсам от недоверяемого загруженного кода, работающего в пределах виртуальной машины Java. Менеджер безопасности определяет, имеет ли загруженный код доступ к локальной файловой системе или может выполнить какие-либо другие привилегированные операции.

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

Вот код, который создает и устанавливает менеджера безопасности:

if (System.getSecurityManager() == null) {
    System.setSecurityManager(new SecurityManager());
}

Делать Удаленный объект, Доступный для Клиентов

Затем, main метод создает экземпляр ComputeEngine и экспорт это ко времени выполнения RMI со следующими операторами:

Compute engine = new ComputeEngine();
Compute stub =
    (Compute) UnicastRemoteObject.exportObject(engine, 0);

Помехи UnicastRemoteObject.exportObject метод экспортирует предоставленный удаленный объект так, чтобы это могло получить вызовы своих удаленных методов от удаленных клиентов. Второй параметр, int, определяет который порт TCP использовать, чтобы прислушаться к входящим удаленным запросам вызова на объект. Распространено использовать нуль значения, который определяет использование анонимного порта. Фактический порт будет тогда выбран во времени выполнения RMI или базовой операционной системой. Однако, ненулевое значение может также использоваться, чтобы определить определенный порт, чтобы использовать для того, чтобы слушать. Однажды exportObject вызов возвратился успешно, ComputeEngine удаленный объект готов обработать входящие удаленные вызовы.

exportObject метод возвращает тупик для экспортируемого удаленного объекта. Отметьте что тип переменной stub должен быть Compute, нет ComputeEngine, потому что тупик для удаленного объекта только реализует удаленные интерфейсы, которые реализует экспортируемый удаленный объект.

exportObject метод объявляет, что может бросить a RemoteException, который является проверенным типом исключения. main метод обрабатывает это исключение с try/catch блок. Если исключение не было обработано таким образом, RemoteException должен был бы быть объявлен в throws пункт main метод. Попытка экспортировать удаленный объект может бросить a RemoteException если необходимые коммуникационные ресурсы не доступны, такой, как будто требуемый порт направляется в некоторой другой цели.

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

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

java.rmi.registry.Registry удаленный интерфейс является API для того, чтобы связать (или зарегистрироваться) и искать удаленные объекты в реестре. java.rmi.registry.LocateRegistry class обеспечивает статические методы для того, чтобы они синтезировали удаленную ссылку на реестр в определенном сетевом адресе (узел и порт). Эти методы создают удаленный ссылочный объект, содержащий указанный сетевой адрес, не выполняя удаленной передачи. LocateRegistry также обеспечивает статические методы для того, чтобы они создали новый реестр в текущей виртуальной машине Java, хотя этот пример не использует те методы. Как только удаленный объект регистрируется в реестре RMI на локальном узле, клиенты на любом узле могут искать удаленный объект по имени, получить его ссылку, и затем вызвать удаленные методы на объект. Реестр может быть совместно использован всеми серверами, работающими на узле, или отдельный серверный процесс может создать и использовать свой собственный реестр.

ComputeEngine class создает имя для объекта со следующим оператором:

String name = "Compute";

Код тогда добавляет имя к реестру RMI, работающему на сервере. Этот шаг делается позже со следующими операторами:

Registry registry = LocateRegistry.getRegistry();
registry.rebind(name, stub);

Это rebind вызов делает удаленный звонок в реестр RMI на локальном узле. Как любой удаленный вызов, этот вызов может привести к a RemoteException быть брошенным, которое обрабатывается catch блок в конце main метод.

Отметьте неотступно следование Registry.rebind вызов:

Как только сервер зарегистрировался в локальном реестре RMI, он печатает сообщение, указывающее, что это готово начать обрабатывать вызовы. Затем, main метод завершается. Не необходимо иметь поток, ожидают, чтобы поддержать сервер. Пока есть ссылка на ComputeEngine объект в другой виртуальной машине Java, локальной или удаленной, ComputeEngine объект не будет выключен или собрал "мусор". Поскольку программа связывает ссылку на ComputeEngine в реестре это достижимо от удаленного клиента, реестр непосредственно. Система RMI сохраняет ComputeEngine's выполнение процесса. ComputeEngine доступно, чтобы принять вызовы и не будет исправлен, пока его привязка не удаляется из реестра, и никакие удаленные клиенты не содержат удаленную ссылку на ComputeEngine объект.

Заключительная часть кода в ComputeEngine.main метод обрабатывает любое исключение, которое могло бы возникнуть. Единственный проверенный тип исключения, который мог быть добавлен код, RemoteException, любой UnicastRemoteObject.exportObject вызов или реестром rebind вызов. В любом случае программа не может сделать намного больше чем выход после печати сообщения об ошибке. В некоторых распределенных приложениях, восстанавливаясь с отказа сделать удаленный вызов возможно. Например, приложение могло попытаться повторить работу или выбрать другой сервер, чтобы продолжать работу.


Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Разработка Удаленного Интерфейса
Следующая страница: Создание Клиентской Программы