Загрузчик класса апплета не может найти класс в банке апплета - PullRequest
4 голосов
/ 16 мая 2009

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


У меня проблема с апплетом (на самом деле JApplet ), который не может создать экземпляр другого класса, который включен в тот же jar, что и апплет. Исключение, которое я вижу на консоли Java:

Exception in thread "thread applet-com.company.program.cm.hmi.MediatorApplet-1" java.lang.NoClassDefFoundError: com/company/program/cm/cs/JDataStore
    at com.company.program.cm.hmi.MediatorApplet.getMediator(MediatorApplet.java:63)
    at com.company.program.cm.hmi.MediatorApplet.init(MediatorApplet.java:49)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.company.program.cm.cs.JDataStore
    at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClassInternal(Unknown Source)
    ... 4 more
Caused by: java.io.IOException: open HTTP connection failed:http://localhost:8080/TransportHMI/pages/com/company/program/cm/cs/JDataStore.class
    at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    ... 8 more

Я знаю, что класс JDataStore включен в банку. Если я перечислю содержимое с помощью jar tvf CM_Library.jar, я увижу, что оно находится в соответствующей упаковке. Однако приведенные выше исключения из цепочки наводят меня на мысль, что загрузчик классов не ищет в архиве JDataStore, а вместо этого ищет файл JDataStore.class на веб-сервере. Почему это? Загрузчик классов знает, как загрузить класс MediatorApplet из jar-файла, почему он не проверяет его и на JDataStore? В случае, если я не указал параметры правильно в теге апплета, я включу это и здесь:

<applet id="mediator-applet"
        width="0"
        height="0"
        codebase="./"
        archive="CM_Library.jar"
        code="com.company.program.cm.hmi.MediatorApplet">
</applet>

1 Ответ

8 голосов
/ 16 мая 2009

Нашел ответ, посмотрев на предложение , опубликованное для связанного вопроса . Ответ Эдди не решил эту конкретную проблему, но он дал мне решение для моей.

Что не особенно очевидно из моего вопроса, так это то, что класс JDataStore наследует от другого класса, который содержится в другом фляге. Мне не приходилось разбираться с деталями реализации JDataStore в течение нескольких месяцев, поэтому я полностью забыл, что его родительский класс org.json.simple.JSONObject не находится в CM_Library.jar, а находится в json_simple-1.0. .2.jar. Исправление довольно простое, просто скопируйте отсутствующий jar в каталог codebase и добавьте отсутствующий jar в список архивов через запятую в атрибуте archive тега апплета:

<applet id="mediator-applet"
        width="0"
        height="0"
        codebase="./"
        archive="CM_Library.jar, json_simple-1.0.2.jar"
        code="com.company.program.cm.hmi.MediatorApplet">
</applet>

Это исправляет ошибку. Сообщение об исключении не особенно полезно. Это заставит вас поверить, что он вообще не может найти класс, когда реальная проблема заключается в том, что он не может загрузить суперкласс для запрошенного класса.

...