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

URL.getURLStreamHandler should use Thread.getContextClassLoader() classloader

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • 1.3.1, 1.4.0, 1.4.1, 6
    • core-libs
    • x86
    • linux, windows_nt, windows_xp



      Name: nt126004 Date: 03/06/2002


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

      FULL OPERATING SYSTEM VERSION : Debian 3.0 (Sid)


      ADDITIONAL OPERATING SYSTEMS : All platforms (it's a
      library issue)



      A DESCRIPTION OF THE PROBLEM :
      URL.getURLStreamHandler tries to load Handlers according
      to the java.protocol.handler.pkgs system property. It
      does this by trying to load the Handler class
      via the Class.forName() and SystemClassLoader. This does
      not work when a Servlet tries to add a resource handler
      that is included in the WEB-INF part of a .war. This is
      because these classes are loaded neither by the System
      classloader, nor the loader that loaded java.lang.URL
      (which presumably is also the systemclassloader). In
      Java2 a new ClassLoader reference mechanism was added:
      the Thread context classloader
      (Thread.getContextClassLoader()). The URL class should
      also try this loader as otherwise the resource-handler
      should be included on the system classpath with is not
      always possible.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create a servlet that includes a custom resource
      handler in it's WEB-INF/lib directory.
      2. Set the -Djava.protocol.handler.pkgs property to the
      package of the resource handler.
      3. Start this servlet under Tomcat 4.0.2
      4. See the Handler NOT get loaded

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      I expected the URL class to honour the setting of the
      java.protocol.handler.pkgs property, instead it only tried
      to load the Handler from the system-provided classes.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      A testcase would be too long for this box. E-mail me for more information.
      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Include the resource handler on the system-classpath
      (NOTE: this is a temporary solution, as an ISP/ASP is
      unlikely to allow this on a shared hosting system!)
      (Review ID: 139951)
      ======================================================================

      Name: nt126004 Date: 03/06/2002


      FULL PRODUCT VERSION :
      java version "1.3.1_02"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_02-b02)
      Java HotSpot(TM) Client VM (build 1.3.1_02-b02, mixed mode)


      FULL OPERATING SYSTEM VERSION :

      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      URL.getURLStreamHandler() does not consult the
      Thread.currentThread().getContextClassLoader() when
      looking for handler classes with package prefix names in
      java.protocol.handler.pkgs

      Since, URL.getURLStreamHandler() calls Class.forName
      (String), which will:

        return forName0(className, true,
      ClassLoader.getCallerClassLoader());

      If I understand this correctly, then the return of
      ClassLoader.getCallerClassLoader() will be the system or
      rather bootsrap CL, since that is what has loaded URL
      (URL.class.getClassLoader() returns null).

      So any attempt to Class.forName() done in URL will only
      succeed in load classed from the bootstrap cl.

      Back in URL, after failing to Class.forName() it will try
      the system cl and then give up.

      Looks like unless there are class on the system or
      bootstrap cl then Class.forName() just won't work.

      URL should be fixed to load from TCL which should fix this
      problem.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Too complicated to list actual steps. Setup a cl which
      loads the bulk of your classes which includes the protcol
      handler. Set java.protocol.handler.pkgs with the correct
      prefix.

      Create a new instance of a class using the cl you made,
      have that class create a URL with a custom protocol.

      It will never work.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      URL.getURLStreamHandler() should do this:

      try {
         ClassLoader cl = Thread.currentThread
      ().getContextClassLoader();
         if (cl != null) {
            cls = cl.loadClass(clsName);
         }
         if (cls == null) {
            cls = Class.forName(clsName);
         }
      }
      catch (ClassNotFoundException e)
         ClassLoader cl = ClassLoader.getSystemClassLoader();
         if (cl != null) {
            cls = cl.loadClass(clsName);
         }
      }

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      too complicated.
      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      Use a URLStreamHandlerFactory which will load from TCL.
      (Review ID: 143413)
      ======================================================================

            chegar Chris Hegarty
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: