Spec-Zone .ru
спецификации, руководства, описания, API
|
Это учебное руководство организуется следующим образом:
Одна из старших значащих возможностей платформы Java™ является возможностью динамически загрузить программное обеспечение Java с любого Универсального Локатора Ресурса (URL) к виртуальной машине (VM), работающий в отдельном процессе, обычно на различной физической системе. Результат состоит в том, что удаленная система может выполнить программу, например апплет, который никогда не устанавливался на его диске. Для первых немногих разделов этого документа будет обсуждена кодовая база относительно апплетов, чтобы помочь описать кодовую базу относительно Java Удаленный Вызов метода (Java RMI).
Например, VM, работающий изнутри веб-браузера, может загрузить байт-коды для подклассов java.applet.Applet
и любые другие классы необходимы тому апплету. Система, на которой работает браузер, наиболее вероятно никогда не выполняла этот апплет прежде, ни устанавливала его на его диске. Как только все необходимые классы были загружены с сервера, браузер может запустить выполнение программы апплета, используя локальные ресурсы системы, на которой работает клиентский браузер.
RMI Java использует в своих интересах эту возможность загрузить и выполнить классы и на системах, где те классы никогда не устанавливались на диске. Используя Java API RMI любой VM, не только те в браузерах, может загрузить любой Java файл class включая специализированный Java классы тупика RMI, которые включают выполнению вызовов метода на удаленном сервере, используя системные ресурсы сервера.
Понятие кодовой базы происходит из использования ClassLoader
s в языке программирования Java. Когда программа Java использует a ClassLoader
, тот загрузчик class должен знать расположение (я), из которого нужно позволить загрузить классы. Обычно, загрузчик class используется в соединении с сервером HTTP, который подает скомпилированные классы для платформы Java. Наиболее вероятно, первое ClassLoader
/ кодовая база, соединяющая это, Вы вошли в контакт с, был AppletClassLoader
, и часть "кодовой базы" <applet>
HTML-тэг, таким образом, это учебное руководство предположит, что у Вас есть некоторый опыт с Java программирование RMI, так же как запись файлов HTML, которые содержат теги апплета. Например, источник HTML будет содержать что-то как:
<applet height=100 width=100 codebase="myclasses/" code="My.class"> <param name="ticker"> </applet>
Кодовая база может быть определена как источник, или место, из которого можно загрузить классы в виртуальную машину. Например, если бы Вы пригласили нового друга к себе на обед, то Вы должны были бы дать тому другу направления месту, где Вы жили, так, чтобы он или она мог определить местоположение Вашего дома. Точно так же можно думать о кодовой базе как о направлениях, которые Вы даете VM, таким образом, это может найти Ваш [потенциально отдаляют] классы.
Можно думать о Вашем CLASSPATH
как "локальная кодовая база", потому что это - список мест на диске, из которого Вы загружаете локальные классы. Загружая классы из локального находящегося на диске источника, Вашего CLASSPATH
с переменной консультируются. Ваш CLASSPATH
может быть установлен взять или относительные или абсолютные пути к каталогам и/или архивам файлов class. Так так же, как CLASSPATH
своего рода "локальная кодовая база", кодовая база, используемая апплетами и удаленными объектами, может считаться "удаленной кодовой базой".
Чтобы взаимодействовать с апплетом, тот апплет и любые классы, которые это должно выполнить, должны быть доступными удаленными клиентами. В то время как к апплетам можно получить доступ от"ftp://
"или локальный"file:///
"URL, к ним обычно получают доступ от удаленного сервера HTTP.
CLASSPATH
Рисунок 1: Загрузка апплетов
Кодовая база апплета всегда относительно URL страницы HTML в который <applet>
тег содержится.
Используя Java RMI, приложения могут создать удаленные объекты, которые принимают вызовы метода от клиентов в другом VMs. Для клиента, чтобы вызвать методы на удаленном объекте, у клиента должен быть способ связаться с удаленным объектом. Вместо того, чтобы иметь необходимость программировать клиент, чтобы говорить протокол удаленного объекта, Java, RMI использует специальные классы, названные тупиками, которые могут быть загружены на клиент, которые используются, чтобы связаться с (сделайте вызовы метода на), удаленный объект. java.rmi.server.codebase
значение свойства представляет одно или более расположений URL, с которых могут быть загружены эти тупики (и любые классы, необходимые тупикам).
Как апплеты, должны были выполниться классы, удаленные вызовы метода могут быть загружены с"file:///
"URL, но как апплеты,"file:///
"URL обычно требует, чтобы клиент и сервер находились на том же самом физическом узле, если файловая система, упомянутая URL, не делается доступным использованием некоторого другого протокола, такого как NFS.
Обычно, классы должны были выполниться, удаленные вызовы метода должны быть сделаны доступными из сетевого ресурса, такого как сервер FTP или HTTP.
Рисунок 2: Загрузка Java тупики RMI
java.rmi.server.codebase
свойство. Java сервер RMI регистрирует удаленный объект, связанный с именем, с Java реестр RMI. Набор кодовой базы на сервере VM аннотируется к ссылке удаленного объекта в Java реестр RMI.CLASSPATH
, который всегда ищется перед кодовой базой клиент загрузит class локально. Однако, если определение для тупика не находится в клиенте CLASSPATH
, клиент попытается получить определение class от кодовой базы удаленного объекта.Рисунок 3: Java клиент RMI, делающий удаленный вызов метода
В дополнение к загрузке тупиков и их связанных классов клиентов, java.rmi.server.codebase
свойство может использоваться, чтобы определить расположение, с которого может быть загружен любой class, не только тупики.
Когда клиент делает вызов метода удаленного объекта, метод, который это вызывает, мог быть записан, чтобы не принять параметры или много параметров. Есть три отличных случая, которые могут произойти, основанные на типе (ах) данных параметра (ов) метода.
В первом случае все параметры метода (и возвращаемое значение) являются примитивными типами данных, таким образом, удаленный объект знает, как интерпретировать их как параметры метода, и нет никакой потребности проверить CLASSPATH
или любая кодовая база.
Во втором случае, по крайней мере одном удаленном параметре метода или возвращаемом значении объект, для которого удаленный объект может найти определение class локально в CLASSPATH
.
В третьем случае (показанный как Шаг 6, в рисунке 4), удаленный метод получает объектный экземпляр, для которого удаленный объект не может найти определение class локально в CLASSPATH
. Этот тип удаленного вызова метода иллюстрируется в рисунке 4. class объекта, отправленного клиентом, будет подтипом объявленного типа параметра. Подтип также:
Рисунок 4: Java клиент RMI, делающий удаленный вызов метода, передавая неизвестный подтип как параметр метода
7. Как кодовая база апплета, определенная клиентом кодовая база используется, чтобы загрузить Remote
классы, неудаленные классы, и интерфейсы к другому VMs. Если codebase
свойство устанавливается на клиентском приложении, тогда та кодовая база аннотируется к экземпляру подтипа, когда подтип class загружается клиентом. Если кодовая база не будет установлена на клиенте, то удаленный объект будет по ошибке использовать свою собственную кодовую базу.
В случае апплета значение кодовой базы апплета встраивается в страницу HTML, как мы видели в примере HTML в первом разделе этого учебного руководства.
В случае Java кодовая база RMI, вместо того, чтобы иметь ссылку на class, встроенный в страницу HTML, клиент первые контакты Java реестр RMI для ссылки на удаленный объект. Поскольку кодовая база удаленного объекта может обратиться к любому URL, не только тому, который является относительно известного URL, значения Java, кодовой базой RMI должен быть абсолютный URL к расположению тупикового class и любых других классов, необходимых тупиковому class. Это значение 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"
Любой сериализуемый class, включая Java тупики RMI, может быть загружен, если Ваш Java программы RMI конфигурируется должным образом. Вот условия, при которых будет работать динамическая тупиковая загрузка:
java.rmi.server.codebase
свойство было установлено на программе сервера (или в случае активации, программы "установки"), который делает звонок bind
или rebind
, так, что: codebase
свойством является URL в шаге A и
codebase
свойство является каталогом, оно должно закончиться в запаздывании "/"rmiregistry
не может найти тупиковый class или любой из классов, на которые тупик полагается в CLASSPATH
. Это - так кодовая база, аннотируется к тупику, когда реестр делает свою загрузку class тупика, в результате звонков bind
или rebind
в сервере или коде установки.SecurityManager
это позволяет тупику быть загруженным. В Java 2 SDK, Standard Edition, v1.2 и позже, это означает, что у клиента должен также быть должным образом сконфигурированный файл политики безопасности.Есть две типичных проблемы, связанные с java.rmi.server.codebase
свойство, которые обсуждаются затем.
Первой проблемой, с которой Вы могли бы встретиться, является получение a ClassNotFoundException
пытаясь к bind
или rebind
удаленный объект к имени в реестре. Это исключение обычно происходит из-за уродливого codebase
свойство, приводящее к реестру, не бывшему способному определять местоположение тупиков удаленного объекта или других классов, необходимых тупику.
Важно отметить, что тупик удаленного объекта реализует весь одинаковый интерфейсы как удаленный объект непосредственно, таким образом, те интерфейсы, так же как любые другие пользовательские классы, объявленные как параметры метода или возвращаемые значения, должны также быть доступными для скачивания от указанной кодовой базы.
Наиболее часто это исключение выдается в результате исключения запаздывающей наклонной черты со значения URL свойства. Другие причины включали бы: значением свойства не является URL; путь к классам, определенным в URL, является неправильным или написанным c орфографическими ошибками; тупиковый class или любые другие необходимые классы не все доступны от указанного 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
Второй проблемой, с которой Вы могли встретиться, является получение 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)