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

[PATCH digester]FileNotFoundException if xml rule files are in an ear file

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.3
    • None
    • None
    • Operating System: All
      Platform: PC

    • 11862

    Description

      FileNotFoundException when included xml files are packed into an ear file and
      deploy to a j2ee server.

      The problem is at DigesterParser line#344

      URL fileURL = DigesterRuleParser.this.getClass().getClassLoader().getResource
      (fileName);

      It does not use the Thread.currentThread().getContextClassLoader() to get
      resource and naturally failed under complex j2ee classloader architecture.

      To solve the problem, we can directly change this line to

      URL fileURL = Thread.currentThread().getContextClassLoader().getResource
      (fileName);

      However, since Digester allows us to setClassLoader() or
      setUseContextClassLoader(), I figure that the best solution might be to allow
      passing in a rulesDigester to the FromXmlRuleSet() for loading the rules xml
      files.

      I also add a createDigester in DigesterLoader.java to ease use of the new
      feature.

      The patch file is as follows (based on commons-digester-src-20020820.zip)
      -----------------------------------------------
      diff r -u commons
      digester.orig/src/java/org/apache/commons/digester/xmlrules/DigesterLoader.java
      commons-
      digester/src/java/org/apache/commons/digester/xmlrules/DigesterLoader.java
      — commons-
      digester.orig/src/java/org/apache/commons/digester/xmlrules/DigesterLoader.java
      2002-08-20 02:09:42.000000000 +0800
      +++ commons-
      digester/src/java/org/apache/commons/digester/xmlrules/DigesterLoader.java
      2002-08-20 21:22:55.000000000 +0800
      @@ -74,6 +74,7 @@
      *

      • @author David H. Martin - Initial Contribution
      • @author Scott Sanders - Added ASL, removed external dependencies
        + * @author Henri Chen - Added rulesDigester
        */

      public class DigesterLoader

      { @@ -91,6 +92,24 @@ }

      /**
      + * Creates a new digester and initializes it from the specified XML file.
      + * This constructor allows specifing a rulesDigester to do the XML file
      + * loading; thus no matter the XML files is packed into a jar, a war, or a
      + * ear, the rulesDigester can always find the XML files with properly set
      + * ClassLoader.
      + *
      + * @param rulesXml URL to the XML file defining the digester rules
      + * @param rulesDigester digester to load the specified XML file.
      + * @return a new Digester initialized with the rules
      + */
      + public static Digester createDigester(URL rulesXml, Digester rulesDigester)

      { + RuleSet ruleSet = new FromXmlRuleSet(rulesXml, rulesDigester); + Digester digester = new Digester(); + digester.addRuleSet(ruleSet); + return digester; + }

      +
      + /**

      • Given the digester rules XML file, a class loader, and an XML input
        file,
      • this method parses the input file into Java objects. The class loader
      • is used by the digester to create the Java objects.
        diff r -u commons
        digester.orig/src/java/org/apache/commons/digester/xmlrules/DigesterRuleParser.j
        ava commons-
        digester/src/java/org/apache/commons/digester/xmlrules/DigesterRuleParser.java
          • commons-
            digester.orig/src/java/org/apache/commons/digester/xmlrules/DigesterRuleParser.j
            ava 2002-08-20 02:09:42.000000000 +0800
            +++ commons-
            digester/src/java/org/apache/commons/digester/xmlrules/DigesterRuleParser.java
            2002-08-20 22:40:47.000000000 +0800
            @@ -238,7 +238,7 @@
            digester.addFactoryCreate("*/set-properties-rule", new
            SetPropertiesRuleFactory());
            digester.addRule("*/set-properties-rule", new PatternRule
            (digester, "pattern"));
            digester.addSetNext("*/set-properties-rule", "add", ruleClassName);
      • +
        digester.addRule("*/set-properties-rule/alias", new
        SetPropertiesAliasRule(digester));

      digester.addFactoryCreate("*/set-property-rule", new
      SetPropertyRuleFactory());
      @@ -341,7 +341,7 @@
      */
      private void includeXMLRules(String fileName)
      throws IOException, SAXException, CircularIncludeException {

      • URL fileURL = DigesterRuleParser.this.getClass().getClassLoader
        ().getResource(fileName);
        + URL fileURL = getDigester().getClassLoader().getResource(fileName);
        if (fileURL == null) { throw new FileNotFoundException("File \"" + fileName + "\" not found."); }

        @@ -354,7 +354,11 @@
        DigesterRuleParser includedSet =
        new DigesterRuleParser(targetDigester, patternStack,
        includedFiles);
        includedSet.setDigesterRulesDTD(getDigesterRulesDTD());
        +
        Digester digester = new Digester();
        + digester.setUseContextClassLoader(getDigester
        ().getUseContextClassLoader());
        + digester.setClassLoader(getDigester().getClassLoader());
        + digester.setErrorHandler(getDigester().getErrorHandler());
        digester.addRuleSet(includedSet);
        digester.push(DigesterRuleParser.this);
        digester.parse(fileName);
        @@ -373,7 +377,7 @@
        throws ClassNotFoundException, ClassCastException,
        InstantiationException, IllegalAccessException {

      • Class cls = Class.forName(className);
        + Class cls = Class.forName(className, true, digester.getClassLoader
        ());
        DigesterRulesSource rulesSource = (DigesterRulesSource)
        cls.newInstance();

      // wrap the digester's Rules object, to prepend pattern
      @@ -495,10 +499,10 @@
      if (attributes.getValue("paramcount") == null)

      { // call against empty method callMethodRule = new CallMethodRule(methodName); - + }

      else {
      int paramCount = Integer.parseInt(attributes.getValue
      ("paramcount"));

      • +
        String paramTypesAttr = attributes.getValue("paramtypes");
        if (paramTypesAttr == null || paramTypesAttr.length() == 0)

        { callMethodRule = new CallMethodRule(targetDigester, methodName, @@ -512,9 +516,9 @@ paramTypes.add(tokens.nextToken()); }

        callMethodRule = new CallMethodRule(

      • targetDigester,
      • methodName,
      • paramCount,
        + targetDigester,
        + methodName,
        + paramCount,
        (String[])
        paramTypes.toArray(new String[0]));
        }
        }
        @@ -618,7 +622,7 @@
      • the containing SetPropertiesRule rule.
        */
        protected class SetPropertiesAliasRule extends Rule {
      • +
        /**

      • <p>Base constructor.
        *
        diff r -u commons
        digester.orig/src/java/org/apache/commons/digester/xmlrules/FromXmlRuleSet.java
        commons-
        digester/src/java/org/apache/commons/digester/xmlrules/FromXmlRuleSet.java
          • commons-
            digester.orig/src/java/org/apache/commons/digester/xmlrules/FromXmlRuleSet.java
            2002-08-20 02:09:42.000000000 +0800
            +++ commons-
            digester/src/java/org/apache/commons/digester/xmlrules/FromXmlRuleSet.java
            2002-08-20 21:12:50.000000000 +0800
            @@ -83,6 +83,7 @@
            *
      • @author David H. Martin - Initial Contribution
      • @author Scott Sanders - Added ASL, removed external dependencies
        + * @author Henri Chen - Added rulesDigester
        */
        public class FromXmlRuleSet extends RuleSetBase {

      @@ -98,12 +99,28 @@
      */
      private DigesterRuleParser parser;

      + /**
      + * The digester for loading the rules xml.
      + */
      + private Digester rulesDigester;
      +
      /**

      • * Constructs a FromXmlRuleSet using the default DigesterRuleParser
        + * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
        + * rulesDigester.
      • @param rulesXml the path to the XML document defining the Digester rules
        */
        public FromXmlRuleSet(URL rulesXml) { - this(rulesXml, new DigesterRuleParser()); + this(rulesXml, new DigesterRuleParser(), new Digester()); + }

        +
        + /**
        + * Constructs a FromXmlRuleSet using the default DigesterRuleParser and
        + * a ruleDigester for loading the rules xml.
        + * @param rulesXml the path to the XML document defining the Digester rules
        + * @param ruleDigester the digester to read the rules xml.
        + */
        + public FromXmlRuleSet(URL rulesXml, Digester rulesDigester)

        { + this(rulesXml, new DigesterRuleParser(), rulesDigester); }

      /**
      @@ -111,8 +128,18 @@

      • @param parser an instance of DigesterRuleParser, for parsing the rules
        from XML
        */
        public FromXmlRuleSet(URL rulesXml, DigesterRuleParser parser) { + this(rulesXml, parser, new Digester()); + }

        +
        + /**
        + * @param rulesXml the path to the XML document defining the Digester rules
        + * @param parser an instance of DigesterRuleParser, for parsing the rules
        from XML
        + * @param rulesDigester the digester used to load the Xml rules.
        + */
        + public FromXmlRuleSet(URL rulesXml, DigesterRuleParser parser, Digester
        rulesDigester)

        { xmlRules = rulesXml; this.parser = parser; + this.rulesDigester = rulesDigester; }

      /**
      @@ -129,7 +156,6 @@
      parser.setDigesterRulesDTD(dtdURL.toString());
      parser.setTarget(digester);

      • Digester rulesDigester = new Digester();
        rulesDigester.addRuleSet(parser);
        rulesDigester.push(parser);

      Attachments

        Activity

          People

            Unassigned Unassigned
            henrichen@infoshock.com Henri Chen
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: