解决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=&quot;&quot;
    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.&#160; 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

相关文章:

  1. 解决org.xml.sax.SAXNotRecognizedException异常
  2. 获取AM指定的JDBC Datasource
  3. Ubuntu中安装配置JDK

9 responses to 解决javax.xml.parsers.FactoryConfigurationError

  1. 从大的趋势来说应该是这样的,但是按照Oracle的官方说法,以后Oracle EBS, Peoplesoft和Fusion Apps是独立的产品线,虽然Fusion Apps的功能会综合现有这些应用系统,但是Oracle不会强迫客户从现有的应用系统升级到Fusion Apps。但是估计这只是Oracle的缓兵之计,但不管怎么说,对于我们二次开发人员不断更新开发知识总没有坏处!

  2. 这么说,ORACLE二次开发人员需要尽快更新自己的知识库了

  3. Oracle Fusion Application非常令人期待啊
    若想了解详情可以查看:http://www.oracle.com/us/products/applications/fusion/index.htm

  4. Fusion Apps是完全基于Oracle ADF技术全新设计的下一代应用系统,而不是之前一些人猜测的在现有的Oracle EBS,Peoplesoft和JD基础上集成的系统,因此在Fusion Apps中完全基于Fusion Middleware的Oracle ADF技术,并没有采用Form技术了。

  5. 不好意思,是我搞错了,应该是Fusion Applications
    是不是该版本完全基于JSP页面?FORM是不是淘汰了?

  6. 楼上所说的Oracle下一代产品是指下一代应用产品Fusion Applications还是其它?
    Weblogic可以指应用服务器的称呼,也可以是原来BEA公司产品的平台,不知道LS具体想了解哪些内容?

  7. 据称ORACLE下一代产品都是基于weblogic的,能不能就weblogic做一个最简明的描述呢?

  8. 感谢11分享珍贵的问题经验,为了尊重别人的劳动成果,任何转载都应该表明出处才是!

  9. 该文章属吐血之作,折腾了半天时间,若转载请务必保留全文并标明出处!

Leave a reply

You must be logged in to post a comment.