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

Динамическая загрузка кода, используя Java™ RMI
(Используя java.rmi.server.codebase Свойство)


Это учебное руководство организуется следующим образом:

  1. Начинаясь
  2. Какова кодовая база?
  3. Как это работает?
  4. Используя кодовую базу в Java RMI для больше чем только тупиковой загрузки
  5. Примеры командной строки
  6. Поиск и устранение неисправностей подсказок

1.0 Начинаясь

Одна из старших значащих возможностей платформы Java™ является возможностью динамически загрузить программное обеспечение Java с любого Универсального Локатора Ресурса (URL) к виртуальной машине (VM), работающий в отдельном процессе, обычно на различной физической системе. Результат состоит в том, что удаленная система может выполнить программу, например апплет, который никогда не устанавливался на его диске. Для первых немногих разделов этого документа будет обсуждена кодовая база относительно апплетов, чтобы помочь описать кодовую базу относительно Java Удаленный Вызов метода (Java RMI).

Например, VM, работающий изнутри веб-браузера, может загрузить байт-коды для подклассов java.applet.Applet и любые другие классы необходимы тому апплету. Система, на которой работает браузер, наиболее вероятно никогда не выполняла этот апплет прежде, ни устанавливала его на его диске. Как только все необходимые классы были загружены с сервера, браузер может запустить выполнение программы апплета, используя локальные ресурсы системы, на которой работает клиентский браузер.

RMI Java использует в своих интересах эту возможность загрузить и выполнить классы и на системах, где те классы никогда не устанавливались на диске. Используя Java API RMI любой VM, не только те в браузерах, может загрузить любой файл класса Java включая специализированный Java классы тупика RMI, которые включают выполнению вызовов метода на удаленном сервере, используя системные ресурсы сервера.

Понятие кодовой базы происходит из использования ClassLoaders в языке программирования Java. Когда программа Java использует a ClassLoader, тот загрузчик класса должен знать расположение (я), из которого нужно позволить загрузить классы. Обычно, загрузчик класса используется в соединении с сервером HTTP, который подает скомпилированные классы для платформы Java. Наиболее вероятно, первое ClassLoader/ кодовая база, соединяющая это, Вы вошли в контакт с, был AppletClassLoader, и часть "кодовой базы" <applet> HTML-тэг, таким образом, это учебное руководство предположит, что у Вас есть некоторый опыт с Java программирование RMI, так же как запись файлов HTML, которые содержат теги апплета. Например, источник HTML будет содержать что-то как:

<applet height=100 width=100 codebase="myclasses/" code="My.class">
        <param name="ticker">
</applet>

2.0 Какова кодовая база?

Кодовая база может быть определена как источник, или место, из которого можно загрузить классы в виртуальную машину. Например, если бы Вы пригласили нового друга к себе на обед, то Вы должны были бы дать тому другу направления месту, где Вы жили, так, чтобы он или она мог определить местоположение Вашего дома. Точно так же можно думать о кодовой базе как о направлениях, которые Вы даете VM, таким образом, это может найти Ваш [потенциально отдаляют] классы.

Можно думать о Вашем CLASSPATH как "локальная кодовая база", потому что это - список мест на диске, из которого Вы загружаете локальные классы. Загружая классы из локального находящегося на диске источника, Вашего CLASSPATH с переменной консультируются. Ваш CLASSPATH может быть установлен взять или относительные или абсолютные пути к каталогам и/или архивам файлов класса. Так так же, как CLASSPATH своего рода "локальная кодовая база", кодовая база, используемая апплетами и удаленными объектами, может считаться "удаленной кодовой базой".

3.0 Как это работает?

3.1 Как кодовая база используется в апплетах

Чтобы взаимодействовать с апплетом, тот апплет и любые классы, которые это должно выполнить, должны быть доступными удаленными клиентами. В то время как к апплетам можно получить доступ от"ftp://"или локальный"file:///"URL, к ним обычно получают доступ от удаленного сервера HTTP.

  1. Клиентский браузер запрашивает класс апплета, который не находится в клиенте CLASSPATH
  2. Определение класса апплета (и любой другой класс (ы), в котором это нуждается) загружается от сервера до клиента, использующего HTTP
  3. Апплет выполняется на клиенте
иллюстрирует три шага выше

Рисунок 1: Загрузка апплетов

Кодовая база апплета всегда относительно URL страницы HTML в который <applet> тег содержится.

3.2 Как кодовая база используется в Java RMI

Используя Java RMI, приложения могут создать удаленные объекты, которые принимают вызовы метода от клиентов в другом VMs. Для клиента, чтобы вызвать методы на удаленном объекте, у клиента должен быть способ связаться с удаленным объектом. Вместо того, чтобы иметь необходимость программировать клиент, чтобы говорить протокол удаленного объекта, Java, RMI использует специальные классы, названные тупиками, которые могут быть загружены на клиент, которые используются, чтобы связаться с (сделайте вызовы метода на), удаленный объект. java.rmi.server.codebase значение свойства представляет одно или более расположений URL, с которых могут быть загружены эти тупики (и любые классы, необходимые тупикам).

Как апплеты, должны были выполниться классы, удаленные вызовы метода могут быть загружены с"file:///"URL, но как апплеты,"file:///"URL обычно требует, чтобы клиент и сервер находились на том же самом физическом узле, если файловая система, упомянутая URL, не делается доступным использованием некоторого другого протокола, такого как NFS.

Обычно, классы должны были выполниться, удаленные вызовы метода должны быть сделаны доступными из сетевого ресурса, такого как сервер FTP или HTTP.

иллюстрирует первые 5 шагов тупика downloadling процесс, как упомянуто ниже

Рисунок 2: Загрузка Java тупики RMI

  1. Кодовая база удаленного объекта определяется сервером удаленного объекта, устанавливая java.rmi.server.codebase свойство. Java сервер RMI регистрирует удаленный объект, связанный с именем, с Java реестр RMI. Набор кодовой базы на сервере VM аннотируется к ссылке удаленного объекта в Java реестр RMI.
  2. Java клиент RMI запрашивает ссылку на именованный удаленный объект. Ссылка (тупиковый экземпляр удаленного объекта) - то, что клиент будет использовать, чтобы сделать удаленные вызовы метода удаленного объекта.
  3. Java реестр RMI возвращает ссылку (тупиковый экземпляр) к требуемому классу. Если определение класса для тупикового экземпляра может быть найдено локально в клиенте CLASSPATH , который всегда ищется перед кодовой базой клиент загрузит класс локально. Однако, если определение для тупика не находится в клиенте CLASSPATH, клиент попытается получить определение класса от кодовой базы удаленного объекта.
  4. Клиент запрашивает определение класса от кодовой базы. Кодовой базой, которую использует клиент, является URL, который аннотировался к тупиковому экземпляру, когда тупиковый класс был загружен реестром. Назад в шаге 1, аннотируемый тупик для экспортируемого объекта был тогда зарегистрирован в Java реестр RMI, связанный с именем.
  5. Определение класса для тупика (и любой другой класс (ы), в котором это нуждается) загружается на клиент.
    Отметьте: Шаги 4 и 5 являются шагами sames, которые реестр сделал, чтобы загрузить класс удаленного объекта, когда удаленный объект был связан с именем в (зарегистрированный в) Java реестр RMI. Когда реестр, предпринятый, чтобы загрузить тупиковый класс удаленного объекта, это запрашивало определение класса от кодовой базы, связанной с тем удаленным объектом.
  6. Теперь у клиента есть вся информация, что она должна вызвать удаленные методы на удаленный объект. Тупиковый экземпляр действует как прокси к удаленному объекту, который существует на сервере; так в отличие от апплета, который использует кодовую базу, чтобы выполнить код в его локальном VM, Java, клиент RMI использует кодовую базу удаленного объекта, чтобы выполнить код в другом, потенциально отдалить VM, как иллюстрировано в рисунке 3:
иллюстрирует заключительный шаг вышеупомянутой процедуры

Рисунок 3: Java клиент RMI, делающий удаленный вызов метода

4.0 Используя кодовую базу в Java RMI для больше чем только тупиковой загрузки

В дополнение к загрузке тупиков и их связанных классов клиентов, java.rmi.server.codebase свойство может использоваться, чтобы определить расположение, с которого может быть загружен любой класс, не только тупики.

Когда клиент делает вызов метода удаленного объекта, метод, который это вызывает, мог быть записан, чтобы не принять параметры или много параметров. Есть три отличных случая, которые могут произойти, основанные на типе (ах) данных параметра (ов) метода.

В первом случае все параметры метода (и возвращаемое значение) являются примитивными типами данных, таким образом, удаленный объект знает, как интерпретировать их как параметры метода, и нет никакой потребности проверить CLASSPATH или любая кодовая база.

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

В третьем случае (показанный как Шаг 6, в рисунке 4), удаленный метод получает объектный экземпляр, для которого удаленный объект не может найти определение класса локально в CLASSPATH. Этот тип удаленного вызова метода иллюстрируется в рисунке 4. Класс объекта, отправленного клиентом, будет подтипом объявленного типа параметра. Подтип также:

Иллюстрирует передачу неизвестного подтипа как параметр метода, как описано выше и ниже.

Рисунок 4: Java клиент RMI, делающий удаленный вызов метода, передавая неизвестный подтип как параметр метода

7. Как кодовая база апплета, определенная клиентом кодовая база используется, чтобы загрузить Remote классы, неудаленные классы, и интерфейсы к другому VMs. Если codebase свойство устанавливается на клиентском приложении, тогда та кодовая база аннотируется к экземпляру подтипа, когда класс подтипа загружается клиентом. Если кодовая база не будет установлена на клиенте, то удаленный объект будет по ошибке использовать свою собственную кодовую базу.

5.0 Примеры командной строки

В случае апплета значение кодовой базы апплета встраивается в страницу HTML, как мы видели в примере HTML в первом разделе этого учебного руководства.

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

Отметьте: Когда codebase значение свойства устанавливается в URL каталога, значение должно быть завершено "/".

Примеры

Если расположение Ваших загружаемых классов находится на сервере HTTP, названном "webvector", в каталоге "экспорт" (под веб-корнем), Ваш codebase установка свойства могла бы быть похожей на это:

        -Djava.rmi.server.codebase=http://webvector/export/

Если расположение Ваших загружаемых классов находится на сервере HTTP, названном "webline", в файле JAR, названном "mystuff.jar", в каталоге "общественность" (под веб-корнем), Ваш codebase установка свойства могла бы быть похожей на это:

        -Djava.rmi.server.codebase=http://webline/public/mystuff.jar

Теперь давайте предположим, что расположение Ваших загружаемых классов было разделено между двумя файлами JAR, "myStuff.jar" и "myOtherStuff.jar". Если эти файлы JAR располагаются на различных серверах (названный "webfront" и "webwave"), Ваш codebase установка свойства могла бы быть похожей на это:

        -Djava.rmi.server.codebase="http://webfront/myStuff.jar http://webwave/myOtherStuff.jar"

6.0 Поиск и устранение неисправностей подсказок

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

  1. Тупиковый класс и любой из классов, на которые полагается тупик, подаются от URL, достижимого от клиента.
  2. java.rmi.server.codebase свойство было установлено на программе сервера (или в случае активации, программы "установки"), который делает звонок bind или rebind, так, что:

  3. rmiregistry не может найти тупиковый класс или любой из классов, на которые тупик полагается в CLASSPATH. Это - так кодовая база, аннотируется к тупику, когда реестр делает свою загрузку класса тупика, в результате звонков bind или rebind в сервере или коде установки.
  4. Клиент установил a SecurityManager это позволяет тупику быть загруженным. В Java 2 SDK, Standard Edition, v1.2 и позже, это означает, что у клиента должен также быть должным образом сконфигурированный файл политики безопасности.

Есть две типичных проблемы, связанные с java.rmi.server.codebase свойство, которые обсуждаются затем.

6.1 Если Вы встречаетесь с проблемой, выполняющей Ваш Java сервер RMI

Первой проблемой, с которой Вы могли бы встретиться, является получение a ClassNotFoundException пытаясь к bind или rebind удаленный объект к имени в реестре. Это исключение обычно происходит из-за уродливого codebase свойство, приводящее к реестру, не бывшему способному определять местоположение тупиков удаленного объекта или других классов, необходимых тупику.

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

Наиболее часто это исключение выдается в результате исключения запаздывающей наклонной черты со значения URL свойства. Другие причины включали бы: значением свойства не является URL; путь к классам, определенным в URL, является неправильным или написанным c орфографическими ошибками; тупиковый класс или любые другие необходимые классы не все доступны от указанного URL.

Исключение, с которым можно встретиться в таком случае, было бы похоже на это:

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stub
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
        java.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stub
java.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stub
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Compiled Code)
        at sun.rmi.transport.StreamRemoteCall.executeCall(Compiled Code)
        at sun.rmi.server.UnicastRef.invoke(Compiled Code)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Compiled Code)
        at java.rmi.Naming.rebind(Compiled Code)
        at examples.callback.MessageReceiverImpl.main(Compiled Code)
RemoteException occurred in server thread; nested exception is:
        java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
        java.lang.ClassNotFoundException: examples.callback.MessageReceiverImpl_Stub

6.2 Если Вы встречаетесь с проблемой, выполняющей Ваш Java клиент RMI

Второй проблемой, с которой Вы могли встретиться, является получение a ClassNotFoundException пытаясь к lookup удаленный объект в реестре. Если Вы получаете это исключение в stacktrace, следующем из попытки выполнить Ваш Java клиентский код RMI, то Ваша проблема CLASSPATH с которого Ваш Java был запущен реестр RMI. См. требование C в разделе 6.0. Вот то, на что будет похоже исключение:

java.rmi.UnmarshalException: Return value class not found; nested exception is:
        java.lang.ClassNotFoundException: MyImpl_Stub
        at sun.rmi.registry.RegistryImpl_Stub.lookup(RegistryImpl_Stub.java:109
        at java.rmi.Naming.lookup(Naming.java:60)
        at RmiClient.main(MyClient.java:28)

Другие ресурсы

Если Вы, Ваши вопросы о кодовой базе являются все еще оставшимися без ответа, пожалуйста смотрят через архивы rmi-пользовательской почтовой рассылки сначала.

Можно хотеть подписаться на rmi-пользовательскую почтовую рассылку.


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