Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4711907

(cl spec) Class.getResource{AsStream} makes unspecified changes to resource name

XMLWordPrintable



      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");
          }
      }
      --------------------------------------

      ======================================================================

            iris Iris Clark
            reysunw Rey Rey (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: