这个小程序在冰茶 JRE 中有效吗?
Posted
技术标签:
【中文标题】这个小程序在冰茶 JRE 中有效吗?【英文标题】:Does this applet work in an Iced Tea JRE? 【发布时间】:2011-03-18 19:22:18 【问题描述】:我提到了一个小演示。在 Setting up policies for an Applet embedded in html 中,一位冰茶 JRE 用户评论了该演示。失败的 为他们。他们拒绝允许小程序(从而将其限制在沙盒中)并应该看到 绿色的“这个小程序是沙盒”页面。相反,小程序完全失败了,他们看到了一个“灰色空间” 小程序应该在哪里。
我在警告它试图实例化一个 File
对象,这就是区别。 IE。
Sun/Oracle JRE 将毫无问题地允许它,只是抛出一个安全异常
当小程序尝试创建JFileChooser
时。 OTOH 冰茶 JRE 不允许
File
待创建。
因此,这段代码应该可以解决这个问题。它移动了
JEditorPane
并安装第一个
在new File(..)
调用之前,一条“所有其他方法都失败”消息,然后是绿色的“沙盒”页面。
我的问题是。对于拥有冰茶 JRE 的用户,此代码是否“像宣传的那样工作”?
测试它:
-
访问小程序
pscode.org/test/docload/applet-latest.html
拒绝数字签名的代码。 这对于创建正确的
测试小程序的条件。
观察/报告小程序是否加载绿色
sandbox.html。沙盒
文档将代表修复错误的“成功”。
同样有趣(可能很少)是 Demo of Defensive Loading of Trusted Applets,链接 到小程序页面,小程序中显示的每个 HTML 文件,以及包含 代码和 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()");
【参考方案1】:
这是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
所以,如果我在对话框中按 Cancel,您的小程序代码似乎甚至没有加载。
我认为您在 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 的对话框中也有相同的按钮,但实际上它们的含义不是被问到的。)
【讨论】:
"IcedTea 似乎重新定义了用户按下取消时的操作。公平地说,对话框中的按钮是“运行”和“取消”,而不是“以所有权限运行”和“运行沙盒”。是的。有时我让默认行为使我对其他 JRE 应该如何表现产生一种错误的安全感。似乎需要调用 JS 才能保留 IcedTea 用户(至少)知道出了什么问题。:(感谢您的进一步测试。 另一种可能性是不签署您的小程序并使用javax.jnlp
函数(此处为FileOpenService
)进行本地文件访问 - 然后在需要文件时询问用户,而不是在小程序的开始。 (并且您可以对未打开文件做出反应。)这些功能始终在 IcedTea 上启用,在 Sun 上仅在使用 jnlp_href=...
加载时启用,并且永远不会在当前 Mac 插件(用于 Safari)上启用(这是缺点)。
“这些功能总是在 IcedTea 上启用,在 Sun 上仅在使用 jnlp_href=... 加载时启用,并且永远不会在当前的 Mac 插件(用于 Safari)上启用(这是缺点)。” (叹气)我已经习惯了 API(例如 JMF Performance Pack、SaverBeans)或其他 Java 相关的东西在 Mac 上不起作用。我(不情愿地)放弃了 Mac。前段时间支持。我现在正在努力解决的问题是,我无法成功创建一个将使用 JNLP 服务(如果可用)的小程序,但可以优雅地退回到用于插件 2 之前架构的非 JNLP 启用解决方案!
是否已向冰茶制造商报告此事?如果是这样,请附上错误报告地址,以便跟踪此问题的状态。【参考方案2】:
作为参考,我可以在 Ubuntu 10.04 上使用 IcedTea 1.9.7 确认 @Paŭlo Ebermann 的结果:
$ java -版本 java版本“1.6.0_20” OpenJDK 运行时环境 (IcedTea6 1.9.7) (6b20-1.9.7-0ubuntu1~10.04.1) OpenJDK Client VM(build 19.0-b09,混合模式,共享)appletviewer
显示预期的sandbox 和随后的诊断输出。 Ubuntu 上的 Firefox 仅提供 Run
(受信任)或 Cancel
(无)。
在 Mac OS X 上,Safari 5.05 产生了预期的结果; appletviewer
产生可比较但不相同的输出。
【讨论】:
对不起,我之前忽略了这一点。 感谢您的报告,随时欢迎。我必须回到受信任的小程序的防御性加载页面并将其更新为(尝试)考虑这种替代行为。最简单的方法可能是使用 javascript 来测试出现的小程序。以上是关于这个小程序在冰茶 JRE 中有效吗?的主要内容,如果未能解决你的问题,请参考以下文章