Этот апплет работает в JRE Iced Tea?
Я упомянул небольшое демо. в разделе Настройка политик для апплета, встроенного в HTML, и пользователь JRE Iced Tea прокомментировал эту демонстрацию. не удалось для них. Они отказались разрешить апплет (тем самым ограничив его песочницей) и должны были увидеть страницу "этот апплет в песочнице" зеленого цвета. Вместо этого апплет полностью потерпел неудачу, и они увидели "серое пространство" там, где должен был быть апплет.
Я хочу сказать, что он пытался создать File
объект, который является разницей IE Sun / Oracle JRE разрешит это без проблем, выдав исключение безопасности только тогда, когда апплет попытается создать JFileChooser
, ОТО, чай со льдом JRE не позволяет File
быть созданным.
Таким образом, этот код должен решить эту проблему. Это перемещает создание / добавление JEditorPane
и установка 1-го сообщения "все остальное терпит неудачу", затем зеленая страница "песочница", перед new File(..)
вызов.
Мой вопрос Этот код "работает как рекламируется" для пользователей с JRE Iced Tea?
Чтобы проверить это:
- Посетите апплет по адресу http://pscode.org/test/docload/applet-latest.html
- Отказаться от кода с цифровой подписью. Это очень важно для создания правильных условий для тестирования апплета.
- Наблюдать / сообщать, загружает ли апплет песочницу зеленого цвета. Документ в песочнице будет представлять "успех" в исправлении ошибки.
Также интерес (что может быть небольшим) представляет собой домашнюю страницу для демонстрации защитной загрузки доверенных апплетов, которая ссылается на страницу (ы) апплета, каждый из файлов 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) Начните() стоп() уничтожить ()