Reputation: 31
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 { }
}
Upvotes: 2
Views: 2538
Reputation: 1151
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.
Upvotes: 3
Reputation: 31
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!
Upvotes: 1