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)
+
+ /**
- 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.
diffr -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);
- commons-
-
+
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)
else {
int paramCount = Integer.parseInt(attributes.getValue
("paramcount"));
+
{ callMethodRule = new CallMethodRule(targetDigester, methodName, @@ -512,9 +516,9 @@ paramTypes.add(tokens.nextToken()); }
String paramTypesAttr = attributes.getValue("paramtypes");
if (paramTypesAttr == null || paramTypesAttr.length() == 0)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.
*
diffr -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 @@
*
- commons-
-
- @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()); + }+
{ + this(rulesXml, new DigesterRuleParser(), rulesDigester); }
+ /**
+ * 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)
/**
@@ -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()); + }+
{ xmlRules = rulesXml; this.parser = parser; + this.rulesDigester = rulesDigester; }
+ /**
+ * @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)
/**
@@ -129,7 +156,6 @@
parser.setDigesterRulesDTD(dtdURL.toString());
parser.setTarget(digester);
- Digester rulesDigester = new Digester();
rulesDigester.addRuleSet(parser);
rulesDigester.push(parser);