apache common Digester ClassLoader 问题

来源:互联网 发布:快递单扫描软件 编辑:程序博客网 时间:2024/05/13 12:48
 
apache common Digester ClassLoader 问题
 
现象:
加载war 包中的org.apache.commons.digester.Digester 正常。
把commons-digester.jar放在weblogic 的classpath中出现下面异常
Digester::startElement: Begin event threw exception
java.lang.ClassNotFoundException: com.cattsoft.report.dao.ConnectionConfigDef
        at java.net.URLClassLoader.findClass(URLClassLoader.java(Compiled Code))
        at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code))
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java(Compiled Code))
        at java.lang.ClassLoader.loadClass(ClassLoader.java(Compiled Code))
        at org.apache.commons.digester.ObjectCreateRule.begin(ObjectCreateRule.java:204)
        at org.apache.commons.digester.Rule.begin(Rule.java:152)
        at org.apache.commons.digester.Digester.startElement(Digester.java:1361)
        at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
        at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(Unknown Source)
    
        at org.apache.commons.digester.Digester.parse(Digester.java:1666)
        at com.cattsoft.report.dao.ConnectionConfigReader.read(ConnectionConfigReader.java:22)
        at com.cattsoft.report.dao.ConnectionFactory.<init>(ConnectionFactory.java:27)
        at com.cattsoft.report.dao.ConnectionFactory.initConnectionFactory(ConnectionFactory.java:133)
        at com.cattsoft.report.dao.ConnectionFactory.createConnection(ConnectionFactory.java:146)
        at com.cattsoft.report.dao.DataAccessTools.createConnection(DataAccessTools.java:18)
        at jsp_servlet.__index._jspService(__index.java:151)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:33)
        at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
       
        at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java(Compiled Code))
        at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
<2007-12-4 11时33分45秒 GMT+08:00> <Error> <HTTP> <BEA-101017> <[ServletContext(id=454748088,name=CReport-Web,context-path=/report)] Root cause of ServletException.
java.lang.Exception: xml parse exception
        at com.cattsoft.report.dao.ConnectionConfigReader.read(ConnectionConfigReader.java:36)
        at com.cattsoft.report.dao.ConnectionFactory.<init>(ConnectionFactory.java:27)
        at com.cattsoft.report.dao.ConnectionFactory.initConnectionFactory(ConnectionFactory.java:133)
        at com.cattsoft.report.dao.ConnectionFactory.createConnection(ConnectionFactory.java:146)
        at com.cattsoft.report.dao.DataAccessTools.createConnection(DataAccessTools.java:18)
        at jsp_servlet.__index._jspService(__index.java:151)
        at weblogic.servlet.jsp.JspBase.service(JspBase.java:33)
分析:
Digester类的getClassLoader方法
    /**
     * Return the class loader to be used for instantiating application objects
     * when required. This is determined based upon the following rules:
     * <ul>
     * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
     * <li>The thread context class loader, if it exists and the
     *     <code>useContextClassLoader</code> property is set to true</li>
     * <li>The class loader used to load the Digester class itself.
     * </ul>
     */
    public ClassLoader getClassLoader() {
 
        if (this.classLoader != null) {
            return (this.classLoader);
        }
        if (this.useContextClassLoader) {
            ClassLoader classLoader =
                    Thread.currentThread().getContextClassLoader();
            if (classLoader != null) {
                return (classLoader);
            }
        }
        return (this.getClass().getClassLoader());
 
}
默认使用当前线程上下文的ClassLoader或当前类的ClassLoader
 
解决方法:
1)      通过配置属性
Digester用来解析应用系统的配置文件,其本身也有很可配置的属性。
属性
描述
classLoader
指定类装载器(class loader)。ObjectCreateRule 和 FactoryCreateRule两个规则中,需要动态加载一些类(如那些盛放XML解析出来的数据的javaBean等),装载器可以在次指定。如果不指定,对这此类的加载将会利用线程上下文中的加载器(当useContextClassLoader值为真时)或利用加载Digester的那个加载器。
errorHandler
指定 SAX ErrorHandler,以在出现此类错误时调用。默认情况下,任何解析错误都会被记入日志,Digest会继续进行解析。
namespaceAware
一个布尔值,为真时对XML文件的解析时会考虑元素的域名空间(如不同的域名空间的同名元素会视为不同的元素)
ruleNamespaceURI
指定后续加入的规则所属的命名空间,如果此值为null,则加入的规则不与任何命名空间相联系。
rules
设定规则模板与XML元素的匹配处理程序。由于这个匹配程序是插件式的,所以匹配工作的完成可以用用户定义的匹配程序未完成。默认情况下,使用Digester提供的匹配器。
useContextClassLoader
一个布尔值,为真时FactoryCreateRule 和 ObjectCreateRule 两个规则中对类的装载将会采用当前线程上下文中指定的加载器。默认情况下,对类的动态加载会利用加载Digester的那个装载器。
validating
一个布尔值,为真时解析器会根据DTD内容对XML文档进行合法性检查,默认值是假,解析器只是检查XML是否格式良好(well formed).
 
2)通过 setClassLoader
 /**
     * Set the class loader to be used for instantiating application objects
     * when required.
     *
     * @param classLoader The new class loader to use, or <code>null</code>
     * to revert to the standard rules
     */
    public void setClassLoader(ClassLoader classLoader) {
 
        this.classLoader = classLoader;
 
}
 
如:digester.setClassLoader(this.getClass().getClassLoader());
  
     
 
原创粉丝点击