-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0, 5.0
-
b32
-
generic
-
generic
-
Verified
Name: erR10175 Date: 07/08/2002
New JCK testcases
api/java_lang/Class/index.html#Reflect2[Class2245]
api/java_lang/Class/index.html#Reflect2[Class2246]
fail with the following messages:
Class2245: Failed. unexpected changes detected
Class2246: Failed. unexpected changes detected
because both java.lang.Class.getResource(String name) and
java.lang.Class.getResourceAsStream(String name), while delegating their call
to class loader, make changes to the resource name that are not specified
explicitly in the descriptions of the methods.
The specification of the methods reads:
"This method delegates the call to its class loader, after making these
changes to the resource name: if the resource name starts with "/", it is
unchanged; otherwise, the package name is prepended to the resource name
after converting "." to "/"."
The RI makes the following changes to the resource name that seem reasonable
but are not specified in the documentation explicitly:
1. leading "/" is removed;
2. "/" is inserted between package name and resource name;
3. "." is converted to "/" in the package name, but is left unchanged
in resource name.
The following table shows 5 resource names that tested (the package
name is "p1.p2"):
----------------------------------------------------------------
resource name may be expected made by RI
according to spec
----------------------------------------------------------------
"/" "/" ""
"" "p1.p2" "p1/p2/"
"/repository\\dir/resource.dat"
"/repository\\dir/resource.dat"
"repository\\dir/resource.dat"
"x.y.z" "p1.p2x.y.z" "p1/p2/x.y.z"
"x/y/z" "p1.p2x/y/z" "p1/p2/x/y/z"
----------------------------------------------------------------
To reproduce the first failure compile and run Class2245.java (see below) as
the following log shows:
$java -version && javac Class2245.java && java Class2245; echo $?
java version "1.4.1-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-rc-b15)
Java HotSpot(TM) Client VM (build 1.4.1-rc-b15, mixed mode)
getResource()
getResource(p1/p2/)
getResource(repository\dir/resource.dat)
getResource(p1/p2/x.y.z)
getResource(p1/p2/x/y/z)
unexpected changes detected
1
----------------------- Class2234.java
import java.io.PrintStream;
import java.util.Vector;
import java.net.URL;
/*
* class loader that defines class p1.p2.B
* and hook getResource calls
*/
class ResourceGetter extends ClassLoader {
protected ResourceGetter(ClassLoader parent) {
super(parent);
log = new Vector();
}
public static final String specialClass = "p1.p2.B";
/* bytes of an empty class p1.p2.B
*/
public static final byte[] specialClassCode = {
(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE,
(byte)0x00, (byte)0x03, (byte)0x00, (byte)0x2D,
(byte)0x00, (byte)0x05, (byte)0x07, (byte)0x00,
(byte)0x02, (byte)0x01, (byte)0x00, (byte)0x10,
(byte)0x6A, (byte)0x61, (byte)0x76, (byte)0x61,
(byte)0x2F, (byte)0x6C, (byte)0x61, (byte)0x6E,
(byte)0x67, (byte)0x2F, (byte)0x4F, (byte)0x62,
(byte)0x6A, (byte)0x65, (byte)0x63, (byte)0x74,
(byte)0x07, (byte)0x00, (byte)0x04, (byte)0x01,
(byte)0x00, (byte)0x07, (byte)0x70, (byte)0x31,
(byte)0x2F, (byte)0x70, (byte)0x32, (byte)0x2F,
(byte)0x42, (byte)0x00, (byte)0x20, (byte)0x00,
(byte)0x03, (byte)0x00, (byte)0x01, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x00
};
protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.equals(specialClass)) {
return defineClass(specialClass, specialClassCode, 0, specialClassCode.length);
}
return super.loadClass(name, resolve);
}
public Class loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
public Vector log;
public URL getResource(String name) {
log.add("getResource(" + name + ")");
return getParent().getResource(name);
}
public void printLog() {
for (int i=0; i < log.size(); ++i) {
System.out.println(log.get(i));
}
};
}
public class Class2245 {
public static void exit(int retCode, String msg) {
System.out.println(msg);
System.exit(retCode);
}
public static void main(String[] args) {
ResourceGetter cl = new ResourceGetter(Class2245.class.getClassLoader());
Class c = null;
try {
c = Class.forName(ResourceGetter.specialClass, false, cl);
} catch (ClassNotFoundException e) {
exit(1, "cannot load class " + ResourceGetter.specialClass);
}
String[][] cases = {
{"/", "/"}, // unchanged
{"", "p1.p2"},^G^G^G^G
{"/repository\\dir/resource.dat", "/repository\\dir/resource.dat"}, // unchanged
{"x.y.z", "p1.p2x.y.z"},
{"x/y/z", "p1.p2x/y/z"},
};
boolean result = true;
for (int i = 0; i < cases.length; ++i) {
cl.log.clear();
c.getResource(cases[i][0]);
if (!cl.log.contains("getResource(" + cases[i][1] + ")")) {
cl.printLog();
result = false;
}
}
if (!result) {
exit(1, "unexpected changes detected");
}
exit(0, "OKAY");
}
}
--------------------------------------
======================================================================