Java-апплет не может найти ресурсы в банке при локальном запуске

Проблема: Java-апплет не может загружать ресурсы, расположенные внутри его jar-файла, при локальном запуске на платформах Windows. Тот же самый апплет может загружать ресурсы, если он запускается с веб-сервера, а не запускается локально, или если он запускается локально в системе Linux. Во всех случаях апплет запускается с использованием тега апплета.

Действия по воспроизведению

1) Создайте код класса апплета ниже и создайте банку, содержащую следующее:

  • TestApplet.class
  • iconimg.png
  • test.html
  • Папка META-INF (стандартный манифест с одной строкой: "Manifest-Version: 1.0")

Вот ссылка на файл изображения png, который я использовал: http://fflexibleretirementplanner.com/java/java-test/iconimg.png

В файле test.html одна строка:

<h1>Text from test.html file</h1>

2) создайте launch.html в той же папке, что и test.jar, следующим образом:

<html><center><title>Test Applet</title><applet
archive  = "test.jar"
code     = "TestApplet.class"
name     = "Test Applet"
width    = "250"
height   = "150"
hspace   = "0"
vspace   = "0"
align    = "middle"
mayscript = "true"
></applet></center></html>

3) Если test.jar находится в той же локальной папке, что и launch.html, щелкните launch.html.

4) Обратите внимание, что вызовы getResource () для imgicon.png и test.html возвращают значение null.

5) Загрузите launch.html и test.jar на веб-сервер, загрузите launch.html и обратите внимание, что ресурсы найдены.

TestApplet.java

import java.applet.AppletContext;
import java.io.IOException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TestApplet extends JApplet {
    public TestApplet() {
        try {
            jbInit();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    public void init() {
        JPanel topPanel = new JPanel();
        JLabel iconLabel;
        URL url = TestApplet.class.getClassLoader().getResource("iconimg.png");
        if  (url != null)
            iconLabel = new JLabel(new ImageIcon(url));
        else
            iconLabel = new JLabel("getResource(iconimg.png)==null");
        topPanel.add(iconLabel);

        URL url2;
        url2 = TestApplet.class.getClassLoader().getResource("test.html");
        if (url2 == null) {
            JLabel errorLabel = new JLabel("getResource(test.html) == null");
            topPanel.add(errorLabel);
        } else {
            try {
                JEditorPane htmlPane = new JEditorPane(url2);
                topPanel.add(htmlPane);
            } catch (IOException ioe) {
                System.err.println("Error displaying " + url2);
            }
        }
        getContentPane().add(topPanel);
    }   
  private void jbInit() throws Exception { }
}

person Jim    schedule 10.07.2013    source источник
comment
1) Чтобы быстрее получить более качественную помощь, опубликуйте SSCCE. Для воспроизведения не нужно больше, чем несколько строк. 2) Попробуйте выполнить поиск в базе данных ошибок и, если вы не найдете ничего похожего, создайте новый отчет. Посмотрите, что Oracle может сказать по этому поводу.   -  person Andrew Thompson    schedule 10.07.2013
comment
Попробуйте и TestApplet.class.getResource("/test.html");. Проверить именование с учетом регистра; особенно Apache может находить имена в неправильном регистре.   -  person Joop Eggen    schedule 10.07.2013
comment
Спасибо за предложение. Я отредактировал свой первоначальный пост, чтобы он был более кратким и (надеюсь) следовал формату SSCCE. Я поискал в базе данных ошибок и сообщил об этом как об ошибке. Надеюсь, я делаю не то тупоголовое, что просто не вижу :)   -  person Jim    schedule 11.07.2013
comment
Также для Joop - я пробовал getResource (/test.html) и другие варианты, такие как ./test и т. Д., Но результаты были такими же. Интересно, что апплет работает в программе просмотра апплетов eclipse, используя test.html, ./test.html и даже. \ Test.html, но не /test.html.   -  person Jim    schedule 11.07.2013
comment
Обновление - тестовый апплет отлично работает локально на ubuntu с последней версией java и холодным чаем. Так что, по-видимому, это проблема только с Windows, возможно, специфична для 1.7.0_25 / 40-ea.   -  person Jim    schedule 11.07.2013


Ответы (2)


Oracle решила изменить поведение getDocumentBase (), getCodeBase () и getResource () из соображений безопасности с версии 1.7.0_25 в Windows: http://www.duckware.com/tech/java-security-clusterfuck.html

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

person Jose Miguel Ordax    schedule 04.10.2013

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

Почти наверняка это ошибка java 1.7.0.25. Апплет отлично работает с веб-сервера, а также отлично работает локально в виртуальной системе Ubuntu (с использованием VirtualBox в Windows). Надеюсь, отправленный мною отчет об ошибке будет полезен разработчикам Java.

Спасибо за ответы. Кстати, именно комментарий Джупа о чувствительности к регистру побудил меня протестировать систему Linux просто для удовольствия. Спасибо за это!

person Jim    schedule 10.07.2013