JDK-5103449 : REGRESSION: getResourceAsStream is broken in JDK1.5.0-rc
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.4.2_12,5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_2000,windows_xp
  • CPU: generic,x86
  • Submitted: 2004-09-16
  • Updated: 2004-10-11
  • Resolved: 2004-10-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6
1.4.2_15Resolved 6 b08Fixed
Related Reports
Duplicate :  
Description
Name: rmT116609			Date: 09/16/2004


FULL PRODUCT VERSION :
java version "1.5.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-rc-b63)
Java HotSpot(TM) Client VM (build 1.5.0-rc-b63, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
getResourceAsStream is broken in JDK1.5.0-rc

In versions of Java up to and including JDK1.5.0-beta2 Class.getResourceAsStream(String aName) was returning the Resource as specified in the documentation.

It says aName starting with / it is unchanged.
Now any resources that require Web Address escape codes (%'s) can not be loaded from a jar in this way.

Even some legal java identifiers don't work anymore such as TestM-^O����.class
(The compatibility issues note that only binary names for some methods can be used now, so I thought this might be the case, but  this implies otherwise).

The method is also very inefficient as not just does it get the resource as it should, but then it makes a garbage URL with the % signs in it and does the security checks for a 2nd time and tries to get the Resource for a 2nd time from the garbage URL and then returns null.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
put the class in a jar
run the class with the jar in its classpath

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Resource Found to be displayed
ACTUAL -
Resource Not Found is displayed

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Test case using pound symbol:
public class Test���� {
 public static void main(String[] args) {
   System.out.println(Test����.class.getResourceAsStream("/Test����.class") == null ?
"Resource Not Found" : "Resource Found");
 }
}

Test case using unicode for the pound symbol:
public class Test\u00a3 {
 public static void main(String[] args) {
   System.out.println(Test\u00a3.class.getResourceAsStream("/Test\u00a3.class") == null ?
"Resource Not Found" : "Resource Found");
 }
} 
---------- END SOURCE ----------

Release Regression From : tiger-beta2
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Incident Review ID: 302077) 
======================================================================
###@###.### 10/8/04 16:17 GMT

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang FIXED IN: mustang
28-09-2004

EVALUATION Here is a more complete recipe for reproducing the bug: $ export LANG=en_US $ cat Test.java public class Test { public static void main(String[] args) { System.out.println (Test\u00a3.class.getResourceAsStream("/Test\u00a3.class") == null ? "Resource Not Found" : "Resource Found");}} $ cat Test��.java public class Test\u00a3 { public static void main(String[] args) { System.out.println("Hello");}} $ javac *.java $ jar cMf foo.jar Test��.class $ rm Test��.class $ java -cp .:foo.jar Test With Tiger b61, it prints "Resource Found"; with Tiger b62, it prints "Resource Not Found" ###@###.### 2004-09-16 Given the extremely small volume of changes in b62, it appears very likely that the change below is responsible. Michael McMahon 5077773: Change in behaviour w.r.t jdk1.4.2 when loading resourcebundles [charlie, jdn, jccollet] Redirecting to the JSN team. ###@###.### 2004-09-16 Yes. This is a regression unfortunately caused when we backed out the fix for 4912903. The erroneous change introduced by 4912903, masked a problem in another change (4979820). The specific problem uncovered is that JarURLConnection, which is used for loading resources from Class.getResourceAsStream() (but not resource loading via other APIs), does not handle % encoded URLs correctly. The % encoding was introduced by 4979820, primarily for HTTP resources. JarURLConnection needs to decode any such URL before accessing the JAR file. Will fix this at earliest opportunity. The fix is very small and localized. Fix for mustang, and tiger01 or 02. Some other notes relating to this code: - Resource class redundancy. URLClasspath uses an inner class called Loader to manage the loading of resources. This class has two separate methods getURL() and getInputStream(). We need to be careful to avoid any inconsistency between Loader.getURL().openStream() and Loader.getInputStream(). - related to point above. JarURLConnection not used for loading JAR resources normally (same applies to file: urls). This is because Loader.getInputStream() effectively ignores the URL and just returns a stream direct to the resource. ClassLoader.getResourceAsStream() fetches the URL for the resource and then calls openStream() so that it gets a URLConnection. This explains why getResourceAsStream behaves differently to normal resource loading. - FileURLConnection has had support for decoding % encoded URLs for a long time, but no support was added to JarURLConnection HttpURLConnection does not need it because HTTP servers understand this encoding directly. - Need to maintain consistency between resource loading and class loading. ie. the same algorithm for locating classes and resources must be used in the same class loader. - Need to make sure delegation model is not broken. ie. when loading any resource, must always call the parent first, before trying to load a resource oneself. ###@###.### 2004-09-22
22-09-2004