Этот апплет работает в JRE Iced Tea?

Я упомянул небольшое демо. в разделе Настройка политик для апплета, встроенного в HTML, и пользователь JRE Iced Tea прокомментировал эту демонстрацию. не удалось для них. Они отказались разрешить апплет (тем самым ограничив его песочницей) и должны были увидеть страницу "этот апплет в песочнице" зеленого цвета. Вместо этого апплет полностью потерпел неудачу, и они увидели "серое пространство" там, где должен был быть апплет.

Я хочу сказать, что он пытался создать File объект, который является разницей IE Sun / Oracle JRE разрешит это без проблем, выдав исключение безопасности только тогда, когда апплет попытается создать JFileChooser, ОТО, чай со льдом JRE не позволяет File быть созданным.

Таким образом, этот код должен решить эту проблему. Это перемещает создание / добавление JEditorPane и установка 1-го сообщения "все остальное терпит неудачу", затем зеленая страница "песочница", перед new File(..) вызов.

Мой вопрос Этот код "работает как рекламируется" для пользователей с JRE Iced Tea?

Чтобы проверить это:

  1. Посетите апплет по адресу http://pscode.org/test/docload/applet-latest.html
  2. Отказаться от кода с цифровой подписью. Это очень важно для создания правильных условий для тестирования апплета.
  3. Наблюдать / сообщать, загружает ли апплет песочницу зеленого цвета. Документ в песочнице будет представлять "успех" в исправлении ошибки.

Также интерес (что может быть небольшим) представляет собой домашнюю страницу для демонстрации защитной загрузки доверенных апплетов, которая ссылается на страницу (ы) апплета, каждый из файлов HTML, отображаемых в апплете, и ZIP-архив, содержащий исходный код кода и HTML, и Ant build.xml, чтобы вы могли "делать это дома, дети".

Вот новый код.

package org.pscode.eg.docload;

import java.awt.BorderLayout;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JFileChooser;

import java.net.URL;
import java.net.MalformedURLException;

import java.io.File;
import java.io.IOException;

import java.security.AccessControlException;

/** An applet to display documents that are JEditorPane compatible.
This applet loads in a defensive way in terms of the security environment,
in case the user has refused to accept the digitally signed code. */
public class DocumentLoader extends JApplet {
    JEditorPane document;

    @Override
    public void init() {
        System.out.println("init()");

        JPanel main = new JPanel();
        main.setLayout( new BorderLayout() );
        getContentPane().add(main);

        document = new JEditorPane("text/html",
            "<html><body><h1>Testing</h1><p>Testing security environment..");
        main.add( new JScrollPane(document), BorderLayout.CENTER );
        System.out.println("init(): entering 'try'");

        try {
            // set up the green 'sandboxed URL', as a precaution..
            URL sandboxed = new URL(getDocumentBase(), "sandbox.html");
            document.setPage( sandboxed );

            // It might seem odd that a sandboxed applet can /instantiate/
            // a File object, but until it goes to do anything with it, the
            // JVM considers it 'OK'.  Until we go to do anything with a
            // 'File' object, it is really just a filename.
            System.out.println("init(): instantiate file");
            File f = new File(".");
            System.out.println("init(): file instantiated, create file chooser");
            // Everything above here is possible for a sandboxed applet

            // *test* if this applet is sandboxed
            final JFileChooser jfc =
                new JFileChooser(f); // invokes security check
            jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
            jfc.setMultiSelectionEnabled(false);

            System.out.println(
                "init(): file chooser created, " +
                "create/add 'Load Document' button");
            JButton button = new JButton("Load Document");
            button.addActionListener( new ActionListener(){
                    public void actionPerformed(ActionEvent ae) {
                        int result = jfc.showOpenDialog(
                            DocumentLoader.this);
                        if ( result==JFileChooser.APPROVE_OPTION ) {
                            File temp = jfc.getSelectedFile();
                            try {
                                URL page = temp.toURI().toURL();
                                document.setPage( page );
                            } catch(Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                } );
            main.add( button, BorderLayout.SOUTH );

            // the applet is trusted, change to the red 'welcome page'
            URL trusted = new URL(getDocumentBase(), "trusted.html");
            document.setPage(trusted);
        } catch (MalformedURLException murle) {
            murle.printStackTrace();
            document.setText( murle.toString() );
        } catch (IOException ioe) {
            ioe.printStackTrace();
            document.setText( ioe.toString() );
        } catch (AccessControlException ace) {
            ace.printStackTrace();
            // document should already be showing sandbox.html
        }
    }

    @Override
    public void start() {
        System.out.println("start()");
    }

    @Override
    public void stop() {
        System.out.println("stop()");
    }

    @Override
    public void destroy() {
        System.out.println("destroy()");
    }
}

2 ответа

Решение

Вот вывод на java.stderr (одна половина эквивалента консоли Java - другая половина java.stdout, которая в вашем случае пуста):

net.sourceforge.jnlp.LaunchException: Fatal: Initialization Error: Could not initialize applet.
        at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:604)
        at net.sourceforge.jnlp.Launcher.getApplet(Launcher.java:548)
        at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:729)
Caused by: net.sourceforge.jnlp.LaunchException: Fatal: Launch Error: Jars not verified.
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.checkTrustWithUser(JNLPClassLoader.java:467)
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.initializeResources(JNLPClassLoader.java:410)
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.<init>(JNLPClassLoader.java:168)
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:249)
        at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:575)
        ... 2 more
Caused by: 
net.sourceforge.jnlp.LaunchException: Fatal: Launch Error: Jars not verified.
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.checkTrustWithUser(JNLPClassLoader.java:467)
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.initializeResources(JNLPClassLoader.java:410)
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.<init>(JNLPClassLoader.java:168)
        at net.sourceforge.jnlp.runtime.JNLPClassLoader.getInstance(JNLPClassLoader.java:249)
        at net.sourceforge.jnlp.Launcher.createApplet(Launcher.java:575)
        at net.sourceforge.jnlp.Launcher.getApplet(Launcher.java:548)
        at net.sourceforge.jnlp.Launcher$TgThread.run(Launcher.java:729)
java.lang.NullPointerException
        at net.sourceforge.jnlp.NetxPanel.runLoader(NetxPanel.java:99)
        at sun.applet.AppletPanel.run(AppletPanel.java:380)
        at java.lang.Thread.run(Thread.java:636)
java.lang.NullPointerException
        at sun.applet.AppletPanel.run(AppletPanel.java:430)
        at java.lang.Thread.run(Thread.java:636)
java.lang.Exception: Applet initialization timeout
        at sun.applet.PluginAppletViewer.handleMessage(PluginAppletViewer.java:637)
        at sun.applet.PluginStreamHandler.handleMessage(PluginStreamHandler.java:270)
        at sun.applet.PluginMessageHandlerWorker.run(PluginMessageHandlerWorker.java:82)
java.lang.RuntimeException: Failed to handle message: handle 60822154 for instance 2
        at sun.applet.PluginAppletViewer.handleMessage(PluginAppletViewer.java:660)
        at sun.applet.PluginStreamHandler.handleMessage(PluginStreamHandler.java:270)
        at sun.applet.PluginMessageHandlerWorker.run(PluginMessageHandlerWorker.java:82)
Caused by: java.lang.Exception: Applet initialization timeout
        at sun.applet.PluginAppletViewer.handleMessage(PluginAppletViewer.java:637)
        ... 2 more

Итак, похоже, ваш код апплета даже не загружается, если я нажимаю Отмена в диалоговом окне.

диалог подтверждения

Я думаю, что здесь вы ничего не можете сделать со стороны Java - может быть, вам поможет другая процедура подписания или запуск апплета с помощью JNLP. Или отправка сообщения об ошибке на IcedTea.


Чтобы продемонстрировать это, я создал очень простой апплет, исключив все критически важные из вашего апплета:

package org.pscode.eg.docload;

import java.awt.FlowLayout;
import javax.swing.*;

public class Example extends JApplet {


    JLabel label;

    public void init()
    {
        System.out.println("init()");
        SwingUtilities.invokeLater(new Runnable(){public void run() {
            label = new JLabel("inited.");
            getContentPane().setLayout(new FlowLayout());
            getContentPane().add(label);
        }});
    }

    @Override
    public void start() {
        System.out.println("start()");
        label.setText("started.");
    }

    @Override
    public void stop() {
        System.out.println("stop()");
        label.setText("stopped.");
    }

    @Override
    public void destroy() {
        System.out.println("destroy()");
        label.setText("destroyed.");
    }
}

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

Кажется, IcedTea переопределил, что делать, когда пользователь нажимает "Отмена". Честно говоря, в диалоговом окне есть кнопки "Выполнить" и "Отмена", а не "Выполнить со всеми разрешениями" и "Выполнить в песочнице".

(В диалоге Sun есть те же кнопки, но в действительности они означают нечто иное, чем запрашиваемое.)

Для справки я могу подтвердить результаты @Paŭlo Ebermann, используя IcedTea 1.9.7 в Ubuntu 10.04:

$ java-версия
Java-версия "1.6.0_20"
Среда выполнения OpenJDK (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1~10.04.1)
OpenJDK Client VM (сборка 19.0-b09, смешанный режим, совместное использование)

appletviewer показывает ожидаемую песочницу и текучий диагностический вывод. Firefox на Ubuntu предлагает только Run (доверенный) или Cancel (ничего такого).

$ appletviewer http://pscode.org/test/docload/applet-latest.html
Предупреждение: Не удается прочитать файл свойств AppletViewer: … Использование значений по умолчанию.
в этом()
init (): ввод 'try'
init(): создание файла
init (): создание экземпляра файла, создание выбора файла
java.security.AccessControlException: доступ запрещен (чтение java.util.PropertyPermission user.home)
    в java.security.AccessControlContext.checkPermission(AccessControlContext.java:393)
    в java.security.AccessController.checkPermission(AccessController.java:553)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1302)
    в java.lang.System.getProperty(System.java:669)
    в javax.swing.filechooser.FileSystemView.getHomeDirectory(FileSystemView.java:397)
    в javax.swing.plaf.metal.MetalFileChooserUI.installComponents(MetalFileChooserUI.java:282)
    в javax.swing.plaf.basic.BasicFileChooserUI.installUI(BasicFileChooserUI.java:153)
    в javax.swing.plaf.metal.MetalFileChooserUI.installUI(MetalFileChooserUI.java:155)
    в javax.swing.JComponent.setUI(JComponent.java:651)
    в javax.swing.JFileChooser.updateUI(JFileChooser.java:1781)
    в javax.swing.JFileChooser.setup(JFileChooser.java:374)
    в javax.swing.JFileChooser.(JFileChooser.java:347)
    на javax.swing.JFileChooser.(JFileChooser.java:330)
    в org.pscode.eg.docload.DocumentLoader.init(DocumentLoader.java:57)
    at sun.applet.AppletPanel.run(AppletPanel.java:436)
    на java.lang.Thread.run(Thread.java:636)
Начните()
стоп()
уничтожить ()

В Mac OS X Safari 5.05 дает ожидаемые результаты; а также appletviewer производит сопоставимый, но не идентичный выход.

$ java-версия
Java-версия "1.6.0_24"
Java(TM) SE Runtime Environment (сборка 1.6.0_24-b07-334-9M3326)
Java HotSpot(TM) 64-разрядная серверная виртуальная машина (сборка 19.1-b02-334, смешанный режим)

$ appletviewer http://pscode.org/test/docload/applet-latest.html
в этом()
init (): ввод 'try'
init(): создание файла
init (): создание экземпляра файла, создание выбора файла
java.security.AccessControlException: доступ запрещен (java.io.FilePermission . чтение)
    в java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
    в java.security.AccessController.checkPermission(AccessController.java:546)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
    at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
    в java.io.File.exists(File.java:731)
    в javax.swing.JFileChooser.setCurrentDirectory(JFileChooser.java:548)
    на javax.swing.JFileChooser.(JFileChooser.java:334)
    на javax.swing.JFileChooser.(JFileChooser.java:316)
    в org.pscode.eg.docload.DocumentLoader.init(DocumentLoader.java:57)
    at sun.applet.AppletPanel.run(AppletPanel.java:424)
    на java.lang.Thread.run(Thread.java:680)
Начните()
стоп()
уничтожить ()
Другие вопросы по тегам