【发布时间】:2016-09-06 17:49:06
【问题描述】:
背景:
我们有一个 Oracle 11g 数据库,它运行 JRE 版本 1.6.0_43 的 Java 虚拟机。我们的用户界面托管在 Apache 网络服务器上,该服务器通过 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,即它不再发生。但是有一个新问题。
问题:
新的 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 请求。 我觉得这里真正的问题是,是什么导致只有某些 Oracle 会话无法以提供者的身份访问 Zephyr 类并产生错误?任何想法都将不胜感激。
【问题讨论】:
标签: java plsql oracle11g jvm stax