首页 文章

Oracle JVM运行时错误:找不到提供程序com.sun.xml.stream.ZephyrParserFactory

提问于
浏览
1

Background:

我们有一个运行Java虚拟机的Oracle 11g数据库,其JRE版本为1.6.0_43 . 我们的用户界面托管在Apache Web服务器上,该服务器通过mod-plsql与数据库连接 .

我们有一些PLSQL过程调用存储在数据库中的Java源代码中的Java过程 - 一个例子是我们用来生成XLS文件的Java过程 .

我们以前一直使用Apache POI套件版本3.8使用DOM Parser从XML生成XLS文件,但我们已升级到POI 3.9,以便我们可以使用Streaming XSSF Workbook类来高效生成XLSX文件(SXSSF可用在POI 3.8中,但核心程序dispose()在POI 3.9之前不可用 .

同样出于效率原因,我们在生成XLSX文件时使用StAX解析(XMLStreamReader),而不是我们用于生成XLS的广泛使用内存的DOM Parser方法 .

要在我们的数据库中将Java POI 3.8升级到3.9,我们有两个步骤:

1)在包含POI 3.8套件的 jar 上运行dropjava:

dropjava -user=xxxxxx@xxxxxx poi-3.8-20120326.jar poi-examples-3.8-20120326.jar poi-excelant-3.8-20120326.jar poi-ooxml-3.8-20120326.jar poi-ooxml-schemas-3.8-20120326.jar poi-scratchpad-3.8-20120326.jar lib\commons-logging-1.1.jar lib\junit-3.8.1.jar lib\log4j-1.2.13.jar ooxml-lib\dom4j-1.6.1.jar ooxml-lib\stax-api-1.0.1.jar ooxml-lib\xmlbeans-2.3.0.jar

2)然后我们运行了loadjava命令来安装3.9套件:

loadjava -user=xxxxxx@xxxxxx -genmissing -resolve -force poi-3.9-20121203.jar poi-examples-3.9-20121203.jar poi-excelant-3.9-20121203.jar poi-ooxml-3.9-20121203.jar poi-ooxml-schemas-3.9-20121203.jar poi-scratchpad-3.9-20121203.jar lib\commons-logging-1.1.jar lib\junit-3.8.1.jar lib\log4j-1.2.13.jar ooxml-lib\dom4j-1.6.1.jar ooxml-lib\stax-api-1.0.1.jar ooxml-lib\xmlbeans-2.3.0.jar

XLSX一代起初根本不起作用;我们在运行时在Java中收到了这个异常:

java.lang.ClassCastException

我们没有确认哪个特定类引起了问题,但我们注意到,在安装POI 3.9(包括StAX stax-api-1.0.1 jar)后,我们的Java类库中存在一些重复的数据库 . 具体来说,这些类及其路径是重复的(并导入到我们生成xlsx的Java源代码中):

import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;

推断重复可能导致异常,我们删除了StAX解析器jar(StAX套件在我们的Java版本之前的某个时刻被“折入”到核心JDK,因此可能不需要导入包含的StAX jar与POI 3.9):

dropjava -user=xxxxxx@xxxxxx ooxml-lib\stax-api-1.0.1.jar

这删除了重复的类并解决了ClassCastException,即它不再出现 . 但是有一个新问题 .

Problem:

现在,新的XLSX方法在运行时间歇性地失败并出现此错误:

javax.xml.stream.FactoryFinder$ConfigurationError: Provider com.sun.xml.stream.ZephyrParserFactory not found

有问题的类com.sun.xml.stream.ZephyrParserFactory似乎在我们的数据库中正确安装 . 我们发现删除该类完全破坏了我们的解析,即我们确信该类安装在我们的实时平台上,因为我们的代码大部分时间都可以工作,但如果没有安装该类,它将无法工作 .

该错误大约每10次左右发生一次XLSX生成尝试(我们每次都使用不同的文件和相同的文件进行测试 - 这似乎与XML的内容无关) . 这行代码生成错误:

XMLInputFactory factory = XMLInputFactory.newInstance();

通过一些调查,我们发现错误是否发生取决于哪个Oracle会话正在处理Web服务器收到的初始HTTP请求 . I feel like the real question here is what could be causing only certain Oracle sessions to fail to access the Zephyr class as a Provider and produce the error? 任何想法都将不胜感激 .

2 回答

  • 0

    它可能与 CDATA events 中描述的 CDATA events 的处理有关 .

    根据输入文件,是否触发此事件 . 如果抛出事件,则会出现 Provider com.sun.xml.stream.ZephyrParserFactory not found 错误 .

    您需要调查哪些代码尝试实例化此具体服务提供程序 .

    通常,实现特定接口的服务提供者在Jar文件内的 META-INF/services 目录中声明 . 在这里找到ServiceLoader的描述,它提供 a simple service-provider loading facility

  • 0

    基于:

    how to override a service provider in java

    https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/SJSXP4.html

    您可以为javax.xml.stream.XMLInputFactory设置系统属性,以指定用于在运行时创建XMLInputFactory的实现实例的实现类 .

    我们在db类库中存储的核心Java API中提供了这样的实现类:

    XMLInputFactoryImpl
    

    我们现在在Java过程开始时使用这样的行来为该Oracle会话的持续时间设置一个系统属性:

    System.setProperty("javax.xml.stream.XMLInputFactory", "<class path>XMLInputFactoryImpl");
    

    这似乎解决了我们的一些Oracle会话在运行时遇到的XMLInputFactory服务提供程序混淆 .

相关问题