Spec-Zone .ru
спецификации, руководства, описания, API
|
Этот раздел обсуждает задачу реализации class для вычислить механизма. Вообще, class, который реализует удаленный интерфейс, должен, по крайней мере, сделать следующее:
Программа сервера RMI должна создать начальные удаленные объекты и экспортировать их во время выполнения RMI, которое делает их доступными, чтобы получить входящие удаленные вызовы. Эта процедура установки может или инкапсулироваться в методе реализации удаленного объекта class непосредственно или включена в другой class полностью. Процедура установки должна сделать следующее:
Полная реализация вычислить механизма следует.
class реализует удаленный интерфейс engine.ComputeEngine
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
метод непосредственно клиенту.
Параметры или возвращаемые значения от удаленных методов могут иметь почти любой тип, включая локальные объекты, удаленные объекты, и примитивные типы данных. Более точно к любому объекту любого типа можно передать или от удаленного метода, пока объект является экземпляром типа, который является примитивным типом данных, удаленным объектом, или сериализуемым объектом, что означает, что это реализует интерфейс java.io.Serializable.
Некоторые объектные типы не соответствуют ни одному из этих критериев и таким образом не могут быть переданы к или возвращены из удаленного метода. Большинство этих объектов, таких как потоки или дескрипторы файлов, инкапсулирует информацию, которая имеет смысл только в пределах единственного адресного пространства. Многие из базовых классов, включая классы в пакетах java.lang
и java.util
, реализуйте Serializable
интерфейс.
Управление правил, как параметры и возвращаемые значения передают, следующие:
static
или transient
. Поведение сериализации значения по умолчанию может быть переопределено на class-by-class основание.Передача удаленного объекта ссылкой означает, что любые изменения, произведенные в состоянии объекта удаленными вызовами метода, отражаются в исходном удаленном объекте. Когда удаленный объект передают, только те интерфейсы, которые являются удаленными интерфейсами, доступны получателю. Любые методы, определенные в реализации 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
вызов:
LocateRegistry.getRegistry
синтезирует ссылку на реестр на локальном узле и на порту реестра значения по умолчанию, 1099. Следует использовать перегрузку, которая имеет int
параметр, если реестр создается на порту кроме 1099.ComputeEngine
, никогда не оставляйте виртуальную машину Java, в которой они создавались. Таким образом, когда клиент выполняет поиск в реестре удаленного объекта сервера, копия тупика возвращается. Удаленные объекты в таких случаях таким образом эффективно передает (удаленная) ссылка, а не значением.bind
, unbind
, или rebind
ссылки удаленного объекта с реестром, работающим на том же самом узле. Это ограничение препятствует тому, чтобы удаленный клиент удалил или перезаписал любую из записей в реестре сервера. A lookup
, однако, может требоваться от любого узла, локального или удаленного.Как только сервер зарегистрировался в локальном реестре RMI, он печатает сообщение, указывающее, что это готово начать обрабатывать вызовы. Затем, main
метод завершается. Не необходимо иметь поток, ожидают, чтобы поддержать сервер. Пока есть ссылка на ComputeEngine
объект в другой виртуальной машине Java, локальной или удаленной, ComputeEngine
объект не будет выключен или собрал "мусор". Поскольку программа связывает ссылку на ComputeEngine
в реестре это достижимо от удаленного клиента, реестр непосредственно. Система RMI сохраняет ComputeEngine
's выполнение процесса. ComputeEngine
доступно, чтобы принять вызовы и не будет исправлен, пока его привязка не удаляется из реестра, и никакие удаленные клиенты не содержат удаленную ссылку на ComputeEngine
объект.
Заключительная часть кода в ComputeEngine.main
метод обрабатывает любое исключение, которое могло бы возникнуть. Единственный проверенный тип исключения, который мог быть добавлен код, RemoteException
, любой UnicastRemoteObject.exportObject
вызов или реестром rebind
вызов. В любом случае программа не может сделать намного больше чем выход после печати сообщения об ошибке. В некоторых распределенных приложениях, восстанавливаясь с отказа сделать удаленный вызов возможно. Например, приложение могло попытаться повторить работу или выбрать другой сервер, чтобы продолжать работу.