Spec-Zone .ru
спецификации, руководства, описания, API
|
Это учебное руководство описывает, как реализовать activatable удаленный объект, который использует постоянное состояние в его реализации. Это учебное руководство использует a Setup
программа (описанный в учебном руководстве Используя Активацию: Setup
Программа), который регистрирует информацию о activatable удаленном объекте с JavaTM Удаленный Вызов метода (Java RMI) системный демон активации (rmid
) и затем связывает тупик для того удаленного объекта в rmiregistry
так, чтобы клиенты могли искать это. Можно хотеть считать то учебное руководство перед этим.
У этого учебного руководства есть следующие шаги:
Setup
программаФайлы, необходимые для этого учебного руководства:
Counter.java
- удаленный интерфейс для того, чтобы рассчитатьCounterImpl.java
- "activatable" реализация удаленного интерфейсаCounterClient.java
- клиент, который использует удаленный интерфейсclient.policy
- файл политики безопасности для клиентаЕсть несколько основных способов реализовать activatable удаленный объект. Это учебное руководство описывает, как реализовать activatable удаленный объект, который использует постоянное состояние в его реализации.
Удаленный объект активируется, когда клиент вызывает удаленный метод на тупик для activatable удаленного объекта. Тупик для activatable удаленного объекта содержит ID активации удаленного объекта и информацию о том, как связаться с Java системный демон активации RMI (rmid
) для удаленного объекта. Если тупик не может соединиться с последним - известный адрес (то есть, узел/порт) для удаленного объекта, тупик свяжется с активатором удаленного объекта (rmid
) активировать объект. Когда rmid
получает запрос активации, он запускает группу активации удаленного объекта (или контейнер) виртуальная машина (VM), если группа уже не выполняется, и затем rmid
просит группа делать экземпляр удаленного объекта. Как только группа создает удаленный объект, она возвращает тупик удаленного объекта rmid
который, поочередно, возвращает фактический тупик тупику инициирования так, чтобы тупик инициирования мог обновить свою информацию о том, как связаться с удаленным объектом в будущем.
Прежде, чем любая эта активация может иметь место, приложение должно зарегистрировать информацию о activatable удаленных объектах, которые это должно использовать. Следующее отдельное учебное руководство описывает информацию, необходимую к activatate удаленный объект и как зарегистрировать эту информацию в rmid
:
Этот пример определяет удаленный интерфейс Counter
с единственной работой, increment
. Реализация class CounterImpl
постоянно хранит результат работы increment
в файле, так, чтобы результат increment
работа переживет через активизацию объектов / цикл дезактивации или даже переживет машинную перезагрузку или катастрофический отказ. Сделать всю эту работу, a CounterImpl
объект, когда активировано, нуждается в имени файла, который это будет использовать в чтение и хранить встречные значения. Пользователь может зарегистрировать дескриптор активации, который содержит это имя файла (в a MarshalledObject
) как "данные инициализации". Группа активации объекта передаст эти предварительно зарегистрированные упорядоченные данные (имя файла) конструктору объекта, когда группа создаст объект во время активации.
Удаленный интерфейс examples.activation.Counter
определяется следующим образом:
package examples.activation; import java.rmi.Remote; import java.io.IOException; public interface Counter extends Remote { int increment() throws IOException; }
Реализация class, examples.activation.CounterImpl
, поскольку activatable удаленный объект следующие:
package examples.activation; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.rmi.MarshalledObject; import java.rmi.activation.Activatable; import java.rmi.activation.ActivationID; public class CounterImpl implements Counter { private RandomAccessFile raf; private int count; private final Object countLock = new Object(); public CounterImpl(ActivationID id, MarshalledObject data) throws Exception { if (data != null) { String filename = (String) data.get(); synchronized (countLock) { count = openFile(filename); } System.err.println("count upon activation = " + count); } Activatable.exportObject(this, id, 0); } private int openFile(String filename) throws IOException { if (filename != null && !filename.equals("")) { File file = new File(filename); boolean fileExists = file.exists(); raf = new RandomAccessFile(file, "rws"); return (fileExists) ? raf.readInt() : writeCount(0); } else { throw new IOException("invalid filename"); } } private int writeCount(int value) throws IOException { raf.setLength(0); raf.writeInt(value); return value; } public int increment() throws IOException { synchronized (countLock) { return writeCount(++count); } } }
class CounterImpl
реализует удаленный интерфейс Counter
, но не расширяет class.
class объявляет специального конструктора "активации", которого группа активации вызывает, чтобы создать экземпляр во время процесса активации. Этот специальный конструктор берет два параметра:
ActivationID
, идентификатор для activatable удаленного объекта. Когда приложение регистрирует дескриптор активации в rmid
, rmid
присваивает это ID активации, который обращается к информации, связанной с дескриптором. Этот тот же самый ID активации (также содержавшийся в тупике удаленного объекта) передают этому конструктору, когда удаленный объект активируется.MarshalledObject
это содержит данные инициализации, предварительно зарегистрированные в rmid
. В этом примере упорядоченные данные являются именем файла, содержащего постоянное состояние объекта, которое является последним встречным значением.Конструктор получает имя файла, содержавшееся в MarshalledObject
который передали как второй параметр. Затем, конструктор вызывает локальный метод openFile
открыть файл и возвратить текущее встречное значение. Если файл существует, openFile
метод читает значение, последнее сохраненный к файлу; иначе, это создает новый файл и инициализирует количество, чтобы обнулить. Конструктор тогда вызывает статический метод Activatable.exportObject
, передача реализации непосредственно (this
), ID активации, и номер порта 0
, указание, что объект должен быть экспортирован на анонимном порту TCP. В то время как эта реализация не использует ID активации, который передают в качестве параметра конструктору, другая реализация может хотеть сохранить ID активации для будущего использования, чтобы деактивировать объект, например.
Наконец, class реализует единственный метод удаленного интерфейса, increment
чтобы постепенно увеличить количество, сохраните количество к файлу, и возвратите постепенно увеличенное количество. Отметьте, что есть дефект в реализации writeCount
метод. Если машина отказывает между звонками setLength
и writeInt
, значение счетчика будет потеряно. Создание этой реализации, более устойчивой к катастрофическому отказу, в пределах которого маленькое окно является осуществлением, оставленным читателю.
CounterClient
программа ищет тупик удаленного объекта (тот, который реализует удаленный интерфейс Counter
) в реестре на узле, предоставленном как дополнительный первый параметр, и затем, вызывает тупик increment
метод и дисплеи результат. Когда этот клиент вызовет удаленный метод на тупик, полученный от реестра, удаленный объект уже активируется если не активный.
Источник для программы следующие:
package examples.activation; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class CounterClient { public static void main(String args[]) throws Exception { String hostname = "localhost"; if (args.length < 1) { System.err.println( "usage: java [options] examples.activation.CounterClient [host]"); System.exit(1); } else { hostname = args[0]; } if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } String name = System.getProperty("examples.activation.name"); Registry registry = LocateRegistry.getRegistry(hostname); Counter stub = (Counter) registry.lookup(name); System.err.println("Obtained stub from the registry."); System.err.println("Invoking increment method..."); int count = stub.increment(); System.err.println("Returned from increment remote call."); System.err.println("count = " + count); } }
Эта программа должна быть выполнена следующим образом:
java -cp clientDir \ -Djava.security.policy=client.policy \ -Dexamples.activation.client.codebase=clientCodebase \ -Dexamples.activation.name=name \ examples.activation.CounterClient [host]
где:
Отметьте: rmid
должен работать на его порту значения по умолчанию, и rmiregistry
должен работать на его порту значения по умолчанию (оба на удаленном узле) до выполнения этой программы.
Следующее является примером client.policy
файл, который предоставляет соответствующие полномочия для примеров активации:
grant codeBase "${examples.activation.client.codebase}" { // permissions to read system properties required by the client permission java.util.PropertyPermission "examples.activation.name","read"; // permission to connect to the registry, activation system, and remote host permission java.net.SocketPermission "*:1024-","connect"; };
Кодовая база, которой предоставляют полномочия, является файлом URL, определяющий расположение классов клиента. Этот файл URL является значением examples.activation.client.codebase
системное свойство, определенное, когда клиентская программа выполняется. Клиент нуждается в двух полномочиях:
java.util.PropertyPermission
- считать системное свойство examples.activation.name
это определяет имя для тупика в реестреjava.net.SocketPermission
- соединяться с реестром, системой активации, и узлом удаленного объектаИсходные файлы для этого примера могут быть скомпилированы следующим образом:
javac -d implDir Counter.java CounterImpl.java javac -d clientDir Counter.java CounterClient.java
где implDir является целевым каталогом, чтобы вставить файлы class реализации, и clientDir является целевым каталогом, чтобы вставить файлы class клиента.
Setup
программаКак только Ваша фаза реализации полна, Вы должны зарегистрировать информацию об объекте activatable, таким образом, клиент может использовать это. Setup
программа, описанная учебным руководством Используя Активацию: Setup
Программа, регистрирует дескриптор активации для объекта activatable с rmid
, и затем связывает тупик удаленного объекта в rmiregistry
так, чтобы клиенты могли искать это.
Работать Setup
программа для этого примера, см., что раздел Запускается rmid
, rmiregistry
, и Setup
программа в Setup
учебное руководство по программе, которое описывает, как запустить rmid
, rmiregistry
, и Setup
программа непосредственно.
После того, как Вы работаете rmid
и rmiregistry
как проинструктировано в Setup
учебное руководство, Вы должны будете работать Setup
программа, чтобы зарегистрировать дескриптор активации для activatable возражает, что реализует class examples.activation.CounterImpl
. Следующая командная строка работает Setup
программа, предоставляя соответствующий файл URL для каждой кодовой базы использовала:
java -cp setupDir:implDir \ -Djava.security.policy=setup.policy \ -Djava.rmi.server.codebase=file:/implDir/ \ -Dexamples.activation.setup.codebase=file:/setupDir/ \ -Dexamples.activation.impl.codebase=file:/impDir/ \ -Dexamples.activation.name=examples.activation.Counter \ -Dexamples.activation.policy=group.policy \ -Dexamples.activation.file=file \ examples.activation.Setup examples.activation.CounterImpl
где:
Setup
class программыSetup
программаdata
в дескрипторе активации объектаОтметьте, что у каждого файла URL выше есть необходимая запаздывающая наклонная черта. Примеры группы и файлов политики установки, подходящих для этого учебного руководства, описываются в Setup
учебное руководство, и упоминается ниже:
Вывод от Setup
программа должна быть похожей на это:
Activation group descriptor registered. Activation descriptor registered. Stub bound in registry.
Как только Вы успешно зарегистрировали дескриптор активации для a CounterImpl
реализация, можно выполнить клиентскую программу, которая, во время ее первого выполнения, вызовет объект activatable активироваться.
Следующая командная строка иллюстрирует, как выполнить клиентскую программу, определяя файл URL для клиентской кодовой базы:
java -cp clientDir \ -Djava.security.policy=client.policy \ -Dexamples.activation.client.codebase=file:/clientDir/ \ -Dexamples.activation.name=examples.activation.Counter \ examples.activation.CounterClient [host]
где:
Примечания:
Setup
программа. В этом примере мы использовали имя examples.activation.Counter
.rmid
и rmiregistry
должен работать на узле сервера. Если узел сервера не является локальным узлом, параметр узла должен определить удаленный узел, на котором они работают.Вывод от клиента должен быть похожим на это:
Obtained stub from the registry. Invoking increment method... Returned from increment remote call. count = 1