如果在本地运行,Java applet无法在jar中找到资源

时间:2013-07-10 13:45:42

标签: java applet getresource

问题:在Windows平台上本地运行时,Java applet无法加载位于其jar内的资源。如果从Web服务器启动而不是在本地启动或者在Linux系统上本地启动,则相同的applet可以加载资源。在所有情况下,applet都是使用applet标签启动的。

重现的步骤

1)在下面构建applet类代码并创建一个包含以下内容的jar:

  
      
  • TestApplet.class
  •   
  • iconimg.png
  •   
  • 的test.html
  •   
  • META-INF文件夹(标准清单有一行:“清单 - 版本:1.0”)
  •   

这是我使用的图片png文件的链接:   http://flexibleretirementplanner.com/java/java-test/iconimg.png

文件test.html有一行:

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

2)在test.jar的同一文件夹中创建launch.html,如下所示:

<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)请注意,对于imgicon.png和test.html的getResource()调用都返回null。

5)将launch.html和test.jar上传到Web服务器并加载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 { }
}

2 个答案:

答案 0 :(得分:3)

Oracle决定修改getDocumentBase(),getCodeBase()和getResource()的行为,因为自Windows 1.7.0_25以来的安全原因:http://www.duckware.com/tech/java-security-clusterfuck.html

似乎有很多关于此更改的讨论,因为它打破了一些重要的有效和安全的用例。

答案 1 :(得分:1)

经过进一步研究并发现这是一个仅限Windows的问题,我称之为回答了这个问题。

几乎可以肯定是java 1.7.0.25的bug。小程序从Web服务器运行良好,并且在虚拟Ubuntu系统上本地运行良好(在Windows上使用VirtualBox)。希望我提交的错误报告对java人有用。

感谢您的回复。顺便说一下,这是Joop关于案例敏感性的评论,这促使我只是为了试玩Linux系统。谢谢你!