Java WebStart работает медленно, запрашивая библиотеки из недопустимой папки

Проблема и вопрос: веб-приложение Java ищет свои классы в базовой папке вместо ./lib.

Как было предложено в аналогичном вопросе в приложения Java Web Start неоднократно запрашивают несуществующие файлы, я отключил off подпись jar, чтобы исключить проблему безопасности, и проблема сохраняется.

Ниже приведен чистый пример того, что происходит по сети для этой простой Java-программы:

public static void main(String[] args) {
    // TODO code application logic here
    System.out.println("Hello World! Initializing the class from the jar residing in lib/ folder. Expecting heavy network traffic...");

    //This class resides in lib/SampleJavaLibrary.jar
    //Initializing it just to excercise the class loader problem
    CDummyClass sDummy = new CDummyClass();

    System.out.println("Done");

}

В сети (с помощью wireshark) можно наблюдать повторяющиеся запросы на jar-файлы в базовой папке. На некоторых вызовах я насчитал до 10 повторных попыток, веб-сервер ответил 404. В конечном итоге loadClass успешен, но только после 10 или более запросов. для несуществующих банок. Умножьте это на количество классов, к которым обращаются в данной программе, и вы получите очень медленную инициализацию. В этом простом случае для этого простого класса есть «всего» 2 попытки.

Все запускается нормально, баночки загружаются, все хорошо и приятно:

6   0.020921    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/launch.jnlp HTTP/1.1
8   0.028092    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 200 OK  (application/x-java-jnlp-file)
10  0.514038    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/lib/SampleJavaLibrary.jar HTTP/1.1 
11  0.520688    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 200 OK  (application/java-archive)
12  0.618640    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/WebStartSample.jar HTTP/1.1 
14  0.652541    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 200 OK  (application/java-archive)

Вот тут-то и начинаются проблемы при вызове библиотечного класса:

16  0.943801    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/SampleJavaLibrary.jar HTTP/1.1 
18  0.991748    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 404 Not Found  (text/html)
22  0.997281    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/SampleJavaLibrary.jar HTTP/1.1 
24  1.004799    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 404 Not Found  (text/html)

В конечном итоге, после повторной попытки, описанной выше, класс находится и инициализируется (!), скорее всего, из уже существующего jar-файла, который был загружен при запуске приложения.

Почему загрузчик классов jnlp просматривает базовую папку и почему так много попыток, мне не понятно. Я пробовал запускать под отладчиком, но не смог найти исходников для загрузчиков классов и сам не разобрался.

FWIW вот мой файл jnlp, и да, я пробовал все варианты тега обновления, ленивый, нетерпеливый, никаких изменений

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jnlp codebase="http://mydebian.mydomain/mnt/vbox/workspace/WebStartSample/distC"    href="launch.jnlp" spec="1.0+">
    <information>
        <title>WebStartSample</title>
        <vendor>user</vendor>
        <homepage href=""/>
        <description>WebStartSample</description>
        <description kind="short">WebStartSample</description>

    </information>
<update check="always"/>

    <resources>
<j2se version="1.5+"/>
<jar href="WebStartSample.jar" main="true"/>


    <jar href="lib/SampleJavaLibrary.jar"/>
</resources>
    <application-desc main-class="webstartsample.Main">

    </application-desc>
</jnlp>

Я подозреваю, что что-то не так с JNLPClassLoader(), то есть с конкретным загрузчиком, используемым в веб-старте.

С уважением,

Роберт


person R. Simac    schedule 24.04.2011    source источник
comment
Это JNLP-приложение работало раньше или это новая функциональность?   -  person Thorbjørn Ravn Andersen    schedule 24.04.2011
comment
Какую JVM вы используете? Работает ли он с Sun Java WebStart?   -  person Jarek Przygódzki    schedule 24.04.2011


Ответы (3)


Рекомендации:

  1. Подтвердите JNLP, используя JaNeLA. На мой взгляд, это кажется правильным, но JaNeLA - лучший судья.
  2. Включите элемент package для каждой банки. Этот элемент упоминается в разделе Resources синтаксис файла JNLP (также развернутый в таблице вверху страницы). Перейдите по ссылке на страницу к Спецификации API (только для загрузки), чтобы получить дополнительные сведения об элементе package. И кстати, спецификация API. является единственным лучшим ресурсом на JWS. Я бы хотел, чтобы Oracle сделала его доступным для просмотра в Интернете.
  3. Проиндексируйте файлы Jar.
  4. Продолжайте задавать такие замечательные (хорошо продуманные, хорошо проработанные, хорошо представленные) вопросы. :)
person Andrew Thompson    schedule 24.04.2011
comment
JaNeLA хорошо выглядит. Можно ли его использовать внутри скрипта ant? - person Thorbjørn Ravn Andersen; 24.04.2011
comment
В настоящее время он не предназначен для этого. Сказав это: а) Это с открытым исходным кодом (поэтому возможно все). b) XSD можно извлечь и использовать непосредственно в задаче xmlvalidate на основе Ant. XSD также доступен отдельно. Если вы найдете вдохновение переработать JaNeLA как что-то, что может работать как в задаче Ant, так и в графическом интерфейсе, я буду рад добавить код в исходный код и добавить вас в список участников. ;) - person Andrew Thompson; 24.04.2011
comment
Я как бы надеялся, что смогу использовать его с немного меньшими усилиями, чем то, на что вы намекаете, как шаг в нашем процессе сборки и выпуска. Я увижу, когда появится вдохновение, и тогда вернусь к вам. - person Thorbjørn Ravn Andersen; 24.04.2011

Спасибо всем за предложения. Это был намек Эндрю на «индексацию банок», который указал мне правильное направление...

А именно, jar-файлы (созданные моей текущей IDE, Netbeans) были проиндексированы. Однако META-INF/INDEX.LIST в основной банке содержал ссылки на другие банки, как если бы они находились в текущей папке рядом с основной банкой.

JarIndex-Version: 1.0

WebStartSample.jar
webstartsample

SampleJavaLibrary.jar
newpackage

Это привело к тому, что jnlpClassLoader() использовал основной индекс и искал банки в URL-адресе кодовой базы, хотя они фактически находились в подпапке ./lib url.

Вот так выглядит правильный индекс (созданный вручную):

JarIndex-Version: 1.0

WebStartSample.jar
webstartsample

lib/SampleJavaLibrary.jar
newpackage

Чтобы усугубить проблему, такое веб-приложение не потерпит неудачу, они просто сначала будут искать классы / jar-файлы в неправильных местах, а затем в конечном итоге найдут их, предположительно уже загруженный загрузчик bu jnlp, как описано в исходном вопросе.

Вкратце, эта IS связана с процедурой сборки и упаковки Netbeans.

Мое немедленное исправление заключалось в отключении индексации jar, что привело к правильному и минимальному сетевому трафику и значительно улучшило инициализацию приложения.

Чтобы сделать это в Netbeans, перейдите в Tools->Options->Miscellaneous->Ant->Properties и добавьте jar.index=false

Правильным решением было бы заставить Netbeans правильно индексировать банку, но это другой вопрос.

Еще раз спасибо всем за предложения.

ps.

  • janela util не нашла серьезных ошибок в моем jnlp
  • элемент пакета в том числе без изменений
  • mydebian относится к моему серверу, клиент - win7 со всеми последними и лучшими средами выполнения Java и jdks, включая netbeans 6.9 (также протестирован с 7.0, создан тот же проблемный индекс)
person R. Simac    schedule 24.04.2011
comment
Я только что обнаружил, что это известная ошибка Netbeans, уже исправленная. Однако, если ваш проект был создан с использованием более старой версии IDE netbeans, ошибка сохранится, и существует ручная процедура отключения Java Webstart, удаления файла jnlp-impl.xml и повторного включения Webstart. Дополнительные сведения см. на странице netbeans.org/bugzilla/show_bug.cgi?id=190929. - person R. Simac; 30.04.2011

Имя хоста «mydebian.mydomain» намекает, что вы используете Debian, где OpenJDK является реализацией Java по умолчанию.

Реализация Sun Java WebStart не является частью OpenJDK, поэтому используется альтернативная реализация. Поскольку Java WebStart не имеет официального TCK, в реализации OpenJDK есть небольшие различия и даже ошибки, которые необходимо искать вручную (поскольку официального TCK нет).

Я бы предложил попробовать с Sun JVM (например, в Windows) и посмотреть, изменится ли поведение.

person Thorbjørn Ravn Andersen    schedule 24.04.2011