解决javax.xml.parsers.FactoryConfigurationError
九月 16, 2009 in Oracle 融合中间件
昨天在项目中遇到了一个非常棘手的异常,将开发好的应用发布到WebLogic中,发现日志中产生如下异常提示信息:
<Sep 15, 2009 9:44:17 AM IRKST> <Critical> <WebLogicServer> <BEA-000386> <Server subsystem failed. Reason: javax.xml.parsers.FactoryConfigurationError: Provider com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl not found
javax.xml.parsers.FactoryConfigurationError: Provider com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl not found
at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
at org.apache.openjpa.lib.xml.XMLFactory.<clinit>(XMLFactory.java:60)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
at org.apache.openjpa.lib.meta.XMLMetaDataParser.parseNewResource(XMLMetaDataParser.java:352)
Truncated. see log file for complete stacktrace
>
<Sep 15, 2009 9:44:17 AM IRKST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to FAILED>
<Sep 15, 2009 9:44:17 AM IRKST> <Error> <WebLogicServer> <BEA-000383> <A critical service failed. The server will shut itself down>
<Sep 15, 2009 9:44:17 AM IRKST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to FORCE_SHUTTING_DOWN>
前段时间我曾经发过一篇帖子,是关于说明WebLogic中XML解析器的Bug的,可能有些朋友已经看过,同样是关于XML解析器的,但是今天遇到的这个问题更为刁钻。单纯查看异常信息,发现就是SAXParserFactoryImpl类没有找到,之前经验看来,SAXParserFactoryImpl类是应该存在于 JAVA_HOME下的jre/lib/rt.jarx下com.sun.org.apache.xerces.internal.jaxp的包结构中,于是试图寻找JAVA_HOME,查看WebLogic的DOMAIN_HOME/bin/setDomainEnv.sh,得到如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | ……
BEA_JAVA_HOME=";"
export BEA_JAVA_HOME
SUN_JAVA_HOME=""
export SUN_JAVA_HOME
if [ "${JAVA_VENDOR}" = "BEA" ] ; then
JAVA_HOME="${BEA_JAVA_HOME}"
export JAVA_HOME
else
if [ "${JAVA_VENDOR}" = "Sun" ] ; then
JAVA_HOME="${SUN_JAVA_HOME}"
export JAVA_HOME
else
JAVA_VENDOR="Unknown";
export JAVA_VENDOR
JAVA_HOME="/usr/java6_64";
export JAVA_HOME
fi
fi
…… |
此时突然想起由于客户服务器使用的是AIX操作系统,在JDK的选择上也可能就是用了IBM提供的JDK,与之前开发环境中的Sun的JDK有所不同。于是转入相应的JAVA_HOME对应的目录下(/usr/java6_64),发现其目录下有readmefirst.aix64.txt文件,其部分内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 | IBM 64-bit SDK for AIX, Java Technology Edition, Version 6 ========================================================== This READMEFIRST file applies to Version 6, and to all subsequent releases, modifications, and service refreshes, until otherwise indicated in a new READMEFIRST file. This READMEFIRST file provides release notes that were not incorporated into the User Guides.  This file must be read in conjunction with any User Guides. The SDK provided in this release is functionally equivalent to the Sun FCS version of Java 6 Update 7 Build 02 codebase. IBM provides additional content with the SDK. …… |
通过以上内容就可以证实,服务器使用的JDK的版本为IBM JDK。使用FTP工具下载该目录的JRE/lib目录下的rt.jar,使用解压工具打开该jar进行查看,发现 com.sun.org.apache.xerces.internal.jaxp的包结构下确实不存在SAXParserFactoryImpl类,甚至连该包结构都不存在:
到这里就有点慌神了,一下子不知道该如何应对,不过着急是没用的,不妨静下心来仔细分析一下,既然JDK选择不同,两者又有一些区别,是否是XML解析器也有所不同呢?经过自己的分析和资料查询,终于发现了问题的原因:
最初的xml解析器是sun的Crimson和IBM的Xerces,这两个开源项目都捐给了apache组织,后来Xerces发展很快,Crimon基本没有人使用。虽然Sun在JDK1.5之后也制定了JAXP规范(JSR 206 Java API for XML Processing(JAXP) 1.3)不过却进行了重构,修改了相关的包结构,因此导致XML解析器在Sun的JDK与IBM的JDK中有所不同。
那么知道了原因,现在就要考虑如何解决该问题,此时在服务器的JAVA_HOME/jre/lib目录下发现有名为jaxp.properties.sample的文件,打开该文件,发现包含如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | …… # To improve XML parsing and processing performance, rename this # file to jaxp.properties and copy it into your JRE's lib directory. # You will also need to uncomment the entries below that you want # to use. # # ==================================================================== # #javax.xml.transform.TransformerFactory=com.ibm.xtq.xslt.jaxp.compiler.TransformerFactoryImpl #javax.xml.xpath.XPathFactory=org.apache.xpath.jaxp.XPathFactoryImpl #javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl #javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl #javax.xml.validation.SchemaFactory:http\://www.w3.org/2001/XMLSchema=org.apache.xerces.jaxp.validation.XMLSchemaFactory #javax.xml.datatype.DatatypeFactory=org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl</p> |
看到这里,突然想起,既然该类找不到,根据sample中的提示又标明了我可以使用的解析器为 org.apache.xerces.jaxp.SAXParserFactoryImpl 的XML解析器,何不根据这个文件中描述的内容由我来指定这样的一个类,于是在JAVA_HOME/jre/lib目录下jaxp.properties 文件,其内容如下:
1 2 | javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl |
可以看到,该文件与jaxp.properties.sample中描述的内容略有不同,我认为对于该文件来说,指定这两个属性已经足够,后经验证,也的确如此:)。这里指定了javax.xml.parsers.SAXParserFactory使用的是 org.apache.xerces.jaxp.SAXParserFactoryImpl ,因此就开始考虑哪里才有这样的一个包结构,借助Google搜索了一下,发现符合该包结构组织的jar为xerces.jar,那么索性就将该jar也丢到JAVA_HOME/jre/lib目录下。
到这里还没有完成,为解决WebLogic的XML解析器的Bug,因此之前已经修改过setDomainEnv.sh,这里需要修改SAXParserFactory为新的包结构,修改其中添加的内容为:
1 2 | JAVA_OPTIONS="${JAVA_OPTIONS} -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl"
export JAVA_OPTIONS |
而非原来的:
1 2 | JAVA_OPTIONS="${JAVA_OPTIONS} -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"
export JAVA_OPTIONS |
从理论上来看,至此,所有的设置均以完成,于是尝试重新启动WebLogic,并发布该应用,发现该异常不再提示,问题解决:)
简单进行总结,该异常的解决步骤如下:
1)在IBM JAVA_HOME/jre/lib下添加jaxp.properties文件,目的是为了指定SAXParserFactoryImpl,内容如下:
1 2 | javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl javax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl |
2)在IBM JAVA_HOME/jre/lib下添加xerces.jar
3)在setDomainEnv.sh里添加如下内容:
1 2 | JAVA_OPTIONS="${JAVA_OPTIONS} -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl"
export JAVA_OPTIONS |
相关文章:
aronezhang said on 九月 22, 2009
从大的趋势来说应该是这样的,但是按照Oracle的官方说法,以后Oracle EBS, Peoplesoft和Fusion Apps是独立的产品线,虽然Fusion Apps的功能会综合现有这些应用系统,但是Oracle不会强迫客户从现有的应用系统升级到Fusion Apps。但是估计这只是Oracle的缓兵之计,但不管怎么说,对于我们二次开发人员不断更新开发知识总没有坏处!
老枪 said on 九月 21, 2009
这么说,ORACLE二次开发人员需要尽快更新自己的知识库了
Eleven.Xu said on 九月 20, 2009
Oracle Fusion Application非常令人期待啊
若想了解详情可以查看:http://www.oracle.com/us/products/applications/fusion/index.htm
aronezhang said on 九月 20, 2009
Fusion Apps是完全基于Oracle ADF技术全新设计的下一代应用系统,而不是之前一些人猜测的在现有的Oracle EBS,Peoplesoft和JD基础上集成的系统,因此在Fusion Apps中完全基于Fusion Middleware的Oracle ADF技术,并没有采用Form技术了。
老枪 said on 九月 19, 2009
不好意思,是我搞错了,应该是Fusion Applications
是不是该版本完全基于JSP页面?FORM是不是淘汰了?
aronezhang said on 九月 19, 2009
楼上所说的Oracle下一代产品是指下一代应用产品Fusion Applications还是其它?
Weblogic可以指应用服务器的称呼,也可以是原来BEA公司产品的平台,不知道LS具体想了解哪些内容?
老枪 said on 九月 16, 2009
据称ORACLE下一代产品都是基于weblogic的,能不能就weblogic做一个最简明的描述呢?
aronezhang said on 九月 16, 2009
感谢11分享珍贵的问题经验,为了尊重别人的劳动成果,任何转载都应该表明出处才是!
Eleven.Xu said on 九月 16, 2009
该文章属吐血之作,折腾了半天时间,若转载请务必保留全文并标明出处!