JDK-8020362 : getResource() doesn't locate resources in jar if run locally
  • Type: Bug
  • Component: deploy
  • Affected Version: 7u21
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_7
  • Submitted: 2013-07-10
  • Updated: 2013-07-19
  • Resolved: 2013-07-19
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version  " 1.7.0_21 " 
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)



ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
Problem: Java applet can't load resources located inside its jar when run locally. The same applet can load the resources if it is launched from a web server instead of being launched locally. In both cases applet is launched using the applet tag.

The local security settings don't seem to matter as long as they permit locally launched unsigned applets.

I also tried signing and sandboxing the applet (manifest permissions: sandbox and applet tag permissions sandbox) and got same result.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Build applet class code below and create a jar containing the following:

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

Here's an online 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   =  " 50 " 
  hspace   =  " 0 " 
  vspace   =  " 0 " 
  align    =  " middle " 
  mayscript =  " true " 
></applet></center></html>

3) double click on launch.html



I made a zip archive with all files need and uploaded it here:
  http://flexibleretirementplanner.com/java/java-test/getresource-bug-report.zip

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
iconimg.png file from jar should be displayed in applet window

Text from test.html jar should be displayed in applet window.
ACTUAL -
TestApplet.class.getClassLoader().getResource( " iconimg.png " ) returns null

TestApplet.class.getClassLoader().getResource( " test.html " ) returns null

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
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 { }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Run applet from a web server.  If applet is run from a website instead of locally, both resources are located inside the jar as expected.
Comments
getResource() return null for local applet case is expected, due to the security fix. Otherwise the URL will exposed local file system path information, which should not be available to local applets. Use getResourceAsStream to load the resource contents directly.
19-07-2013

This specific issue is related to loading a resource from the applets jar file. It cannot load the resource. URLClassloader can find the resource, but DeployURLClassPath.checkURL denies permission to access it, so it appears that it cannot be found. This is clearly a change in behavior in the plugin and not related to any changes in URLClassloader, reassigning to the deploy team for further investigation.
18-07-2013

The security fix to have getCodeBase() return null for file applets is because it will expose local file system information (file path), which sandbox applets should not have access to it. If applet need to load resource: - if the resource is in applet JAR(s), they should be able to load it with ClassLoader getResoruceAsStream directly, without needing the codebase information. - if the resource is in arbitary location, not inside applet JAR, they should have other ways to get to that location, since it's not part of the applet resource anyway. (e.g user.home java system property, provided that their applet has all-permissions)
17-07-2013

After tracing URLClassLoader/Path it can be seen that URLClassPath can locate the resource, but DeployURLClassPath.checkURL is determining that there is insufficient privileges to permit access so null ( cannot be found ) is returned. This would appear to be related to a recent deploy security change, 8001167. I will engage someone from the deploy team to see if this is expected behavior.
17-07-2013