Uploaded image for project: 'Commons Digester'
  1. Commons Digester
  2. DIGESTER-23

Digester uses wrong ClassLoader in a web-application context

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 1.0
    • Fix Version/s: None
    • Labels:
      None
    • Environment:

      Operating System: other
      Platform: Other

    • Bugzilla Id:
      2669

      Description

      I'm cross posting this on Struts-dev and Commmons.

      I attempted to incorporate the commons-digester_1.0 into my struts-
      based application. A quick note on how I'm using it: In one of
      my actions, I 'digest' an xml file. The digester.jar,
      collections.jar, and beanutils.jar are all placed in 'WEB-INF/lib'
      for the web-app in question.

      The difficulty that I ran into is that the Digester could not find
      the classes that needed to be instantiated. I found a solution by
      comparing the struts and commons versions of ObjectCreateRule. The
      struts-ObjectCreateRule locates a class using the current-class'
      ClassLoader, while the commons-ObjectCreateRule first tries to use
      the context-ClassLoader that is set in the currentThread.

      struts.digester.ObjectCreateRule (line 151):
      // Instantiate the new object and push it on the context stack
      Class clazz = Class.forName(realClassName);

      commons.digester.ObjectCreateRule (line 156):

      // Check to see if the context class loader is set,
      // and if so, use it, as it may be set in server-side
      // environments and Class.forName() may cause issues
      ClassLoader ctxLoader =
      Thread.currentThread().getContextClassLoader();
      if (ctxLoader == null)

      { clazz = Class.forName(realClassName); }

      else

      { clazz = ctxLoader.loadClass(realClassName); }

      In the commons.digester.ObjectCreateRule, I made the following
      changes, to enforce using the class' ClassLoader:

      ClassLoader ctxLoader =
      Thread.currentThread().getContextClassLoader();
      - if (ctxLoader == null) {
      + if (true) { + System.out.println("OBJECTCREATERULE IS USING Class.forName()..."); clazz = Class.forName(realClassName); } else { clazz = ctxLoader.loadClass(realClassName); }

      And this worked for me. I understand (more or less) the intent behind
      the code in commons-ObjectCreateRule, but I'm not enough of an expert
      in ClassLoaders to suggest a good solution. Craig, can you help out
      on this one? Perhaps, there's something I need to do that does not
      involve changing the commons-digester1.0 at all?

        Attachments

        1. ASF.LICENSE.NOT.GRANTED--patchfile.txt
          3 kB
          Gidado-Yisa Immanuel
        2. ASF.LICENSE.NOT.GRANTED--patchfile.txt
          3 kB
          Gidado-Yisa Immanuel

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              avm3@cdc.gov Gidado-Yisa Immanuel
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: