Как обмануть API сервис-провайдера Java (jaxp) - PullRequest
4 голосов
/ 17 ноября 2010

У меня есть апплет, который должен вызывать JAXP, в частности SAXParserFactory . Теперь, как вы можете видеть из Javadoc, это внутренне использует механизм поставщика услуг, как описано здесь :

В частности, если он не найдет файл ни в одном из JAR-файлов моего приложения с именем META-INF/services/javax.xml.parsers.SAXParserFactory, он попытается извлечь его из базы кода моего приложения. Если мой апплет развернут следующим образом:

<applet code="com.example.applets.MyApplet" 
 codebase="http://www.example.com/myapp/" archive="myapp.jar, dom4j.jar">

Затем он попытается сделать HTTP-запрос к http://www.example.com/myapp/META-INF/services/javax.xml.parsers.SAXParserFactory

Я бы предпочел этого не делать, особенно потому, что мой апплет подписан, и этот дополнительный HTTP-вызов вызывает предупреждение о неподписанном коде .

Теперь очевидное решение состоит в том, чтобы просто поместить файл META-INF / services в мой JAR-файл приложения, как он говорит, но как мне это сделать, но при этом заставить его использовать реализацию JAXP по умолчанию для JRE пользователя? Альтернативно, есть ли способ убедить среду выполнения апплета искать только в моих JAR-файлах, а не в codebase для этого файла?

Примечание: я знаю, что мог бы также развернуть свою собственную копию JAXP-RI, но это довольно тяжело для апплета.

1 Ответ

11 голосов
/ 17 ноября 2010

Отключить поиск по базе кода:

<applet ...>
 <param name="codebase_lookup" value="false">
</applet>

AppletClassLoader проверяет логическое свойство sun.applet.AppletClassLoader.codebaseLookup, на которое может влиять установка вышеуказанного параметра.Метод sun.applet.AppletPanel.init() прочитает параметр и установит его в AppletClassLoader.После отключения AppletClassLoader перестанет выполнять удаленный поиск классов и ресурсов в кодовой базе, то есть URL-адреса, заданного codebase="http://www.example.com/myapp/", и будет искать только пути к архивам и системным классам.

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

Это также задокументировано в JavaSE - Технические примечания -Руководство разработчика плагинов - специальные атрибуты :

codebase_lookup

Когда загрузчику классов апплета требуется загрузить класс или ресурс (например, файлы конфигурации дляподключаемых сервис-провайдеров в каталоге META-INF / services), он сначала ищет нужные файлы в файлах JAR апплета, а затем в базе кода апплета.Обычно апплеты развертываются со всеми необходимыми классами и ресурсами, хранящимися в файлах JAR апплета.В этом случае поиск по базе кода не требуется.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...