2

Problem: Java applet can't load resources located inside its jar when run locally on windows platforms. The same applet can load the resources if it is launched from a web server instead of launched locally or if it's launched locally on a linux system. In all cases the applet is launched using an applet tag.

Steps to reproduce

1) Build applet class code below and create a jar containing the following:

  • TestApplet.class
  • iconimg.png
  • test.html
  • META-INF folder (standard manifest with one line: "Manifest-Version: 1.0")

Here's a link to the image png file I used: http://flexibleretirementplanner.com/java/java-test/iconimg.png

The file test.html has one line:

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

2) create launch.html in same folder as test.jar as follows:

<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) With test.jar in the same local folder as launch.html, click on launch.html

4) Notice that getResource() calls for imgicon.png and test.html both return null.

5) Upload launch.html and test.jar to a web server and load launch.html and notice that the resources are found.

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 { }
}
Jim
  • 31
  • 1
  • 4
  • 1
    1) For better help sooner, post an [SSCCE](http://sscce.org/). It should not take more than a handful of lines to reproduce. 2) Try searching the [bug DB](http://bugs.sun.com/) & if you find nothing similar, raise a new report. See what Oracle has to say on the matter. – Andrew Thompson Jul 10 '13 at 13:51
  • Try `TestApplet.class.getResource("/test.html");` too. Check for case-sensitive naming; especially Apache can find names in wrong case. – Joop Eggen Jul 10 '13 at 14:07
  • Thanks for the suggestion. I edited my initial post to be more concise and to (hopefully) follow the SSCCE format. I searched the bug database and reported this as a bug. Hopefully it's not something boneheaded that I'm doing that I just can't see :) – Jim Jul 10 '13 at 21:23
  • Also to Joop - I tried the getResource("/test.html") and other variations like ./test, etc but results were the same. Interestingly, the applet works in the eclipse applet viewer using "test.html", "./test.html" and even ".\test.html", but not "/test.html". – Jim Jul 10 '13 at 21:30
  • Update - the test applet runs fine locally on ubuntu with the latest version of java and iced tea. So apparently this is a windows only problem, maybe 1.7.0_25/40-ea specific. – Jim Jul 10 '13 at 22:28

2 Answers2

3

Oracle has decided to modify the behavior of getDocumentBase(), getCodeBase() and getResource() because security reasons since 1.7.0_25 on Windows: http://www.duckware.com/tech/java-security-clusterfuck.html

It seems there is a lot of discussion about this change because it breaks some important valid and secure use cases.

Jose Miguel Ordax
  • 1,151
  • 1
  • 9
  • 20
1

After further research and discovering that this is a windows-only problem, I'm calling this one answered.

It's almost certainly a java 1.7.0.25 bug. The applet runs fine from a web server and also runs fine locally on a virtual Ubuntu system (using VirtualBox on windows). Hopefully the bug report i submitted will be helpful to the java folks.

Thanks for the responses. Btw, it was Joop's comment about case sensitivity that spurred me to test a linux system just for kicks. Thanks for that!

Jim
  • 31
  • 1
  • 4