Java 8 XML解析:不同环境下DeferredDocumentImpl与XMLDocument差异问题
问题核心原因
相同代码、XML内容与JDK版本下出现Document类型差异,本质是XML解析器实现类的加载差异,且生产环境的解析过程存在异常:
- 测试环境使用JDK自带的Xerces解析器,返回的
DeferredDocumentImpl是Xerces的延迟加载文档实现,能正常处理XPath表达式。 - 生产环境加载了其他XML解析器实现(比如应用服务器自带的库、第三方依赖中的解析库),返回的
XMLDocument是该解析器的文档类,且从其包含的err、validateErrNodeStr字段来看,生产环境解析XML时存在验证错误或解析异常,导致文档结构不符合预期,XPath无法定位到目标节点。
具体排查方向
- 类路径冲突:检查生产环境的依赖包,确认是否存在
xercesImpl.jar、xml-apis.jar等非JDK自带的XML解析库,这类库会通过JAXP的SPI机制覆盖JDK默认解析器。对比测试环境的依赖列表,移除多余的冲突库。 - 类加载优先级:若生产环境是应用服务器(如WebLogic、Tomcat),服务器自身的类加载规则可能优先加载其lib目录下的XML解析库,而非JDK自带的。可通过调整服务器的类加载策略(比如设置优先使用JDK类库)来解决。
- XML验证配置:检查代码或生产环境的配置,是否开启了XML Schema/DTD验证。如果XML内容不符合验证规则,生产环境的解析器会生成带错误信息的
XMLDocument,而测试环境可能未开启验证或忽略了错误。可关闭不必要的验证,或调整XML内容使其符合验证规则。 - 显式指定解析器:在代码中强制指定使用JDK默认的解析器实现,避免SPI自动加载其他实现:
// 显式指定JDK自带的DocumentBuilderFactory DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance( "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", Thread.currentThread().getContextClassLoader() );
验证方法
- 打印生产环境中
XMLDocument的err和validateErrNodeStr字段内容,获取具体的解析错误信息,针对性修复XML或验证规则。 - 在生产环境中临时替换解析库为JDK默认版本,验证是否能正常返回
DeferredDocumentImpl并正确执行XPath查询。
内容的提问来源于stack exchange,提问作者sparkey
相关产品推荐
相关产品推荐

