3

小さなデモについて触れました。HTMLに埋め込まれたアプレットとIcedTeaJREユーザーのポリシーの設定で、デモについてコメントしました彼らのために失敗しました。彼らはアプレットへの許可を拒否し(それによってそれをサンドボックスに制限しました)、緑色の「このアプレットはサンドボックス化されています」ページを見ることになっていました。代わりに、アプレットは完全に失敗し、アプレットがあるべき場所に「灰色のスペース」が表示されました。

私はそれがFile違いであるオブジェクトをインスタンス化しようとしていたことをWAGしています。IE Sun / Oracle JREは問題なくそれを許可し、アプレットがを作成しようとしたときにのみセキュリティ例外をスローしますJFileChooser。OTOH the Iced Tea JREでは、の作成は許可されていません File

したがって、このコードはその問題を修正するはずです。最初の「他のすべてが失敗しました」メッセージの作成/追加 JEditorPaneとインストールを移動し、次に緑色の「サンドボックス」ページをnew File(..)呼び出しの前に移動します。

私の質問はです。このコードは、Iced Tea JREを使用しているユーザーに対して「宣伝どおりに機能しますか?」

それをテストするには:

  1. pscode.org/test/docload/applet-latest.htmlでアプレットに アクセスします
  2. デジタル署名されたコードを拒否します。 これは、アプレットをテストするための適切な条件を作成するために非常に重要です。
  3. アプレットが緑色の sandbox.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()");
    }
}
4

2 に答える 2

3

これが出力です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 のダイアログには同じボタンがありますが、実際には、求められたものとは別の意味を持っています。)

于 2011-03-18T19:37:54.650 に答える
1

参考までに、Ubuntu10.04でIcedTea1.9.7を使用して@PaŭloEbermannの結果を確認できます。

$ java -version
Javaバージョン「1.6.0_20」
OpenJDKランタイム環境(IcedTea6 1.9.7)(6b20-1.9.7-0ubuntu1〜10.04.1)
OpenJDKクライアントVM(ビルド19.0-b09、混合モード、共有)

appletviewerは、予想されるサンドボックスとフロー診断出力を示しています。Ubuntu上のFirefoxは、Run(信頼できる)またはCancel(何も)のみを提供します。

$ appletviewer http://pscode.org/test/docload/applet-latest.html
警告:AppletViewerプロパティファイルを読み取ることができません:…デフォルトを使用しています。
初期化()
init():「try」と入力します
init():ファイルをインスタンス化します
init():ファイルがインスタンス化され、ファイルチューザーが作成されます
java.security.AccessControlException:アクセスが拒否されました(java.util.PropertyPermission user.home read)
    java.security.AccessControlContext.checkPermission(AccessControlContext.java:393)で
    java.security.AccessController.checkPermission(AccessController.java:553)で
    java.lang.SecurityManager.checkPermission(SecurityManager.java:549)で
    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)で
    sun.applet.AppletPanel.run(AppletPanel.java:436)で
    java.lang.Thread.run(Thread.java:636)で
始める()
止まる()
破壊する()

Mac OS Xでは、Safari5.05で期待どおりの結果が得られます。同等でappletviewerはあるが同一ではない出力を生成します。

$ java -version
Javaバージョン「1.6.0_24」
Java(TM)SEランタイム環境(ビルド1.6.0_24-b07-334-9M3326)
Java HotSpot(TM)64ビットサーバーVM(ビルド19.1-b02-334、混合モード)

$ appletviewer http://pscode.org/test/docload/applet-latest.html
初期化()
init():「try」と入力します
init():ファイルをインスタンス化します
init():ファイルがインスタンス化され、ファイルチューザーが作成されます
java.security.AccessControlException:アクセスが拒否されました(java.io.FilePermission。read)
    java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)で
    java.security.AccessController.checkPermission(AccessController.java:546)で
    java.lang.SecurityManager.checkPermission(SecurityManager.java:532)で
    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)で
    sun.applet.AppletPanel.run(AppletPanel.java:424)で
    java.lang.Thread.run(Thread.java:680)で
始める()
止まる()
破壊する()
于 2011-04-22T08:25:14.477 に答える