J2EE应用Maven打包后调用JDK自带DocumentBuilder而非xml-apis类如何解决
问题本质
该问题核心源于Java默认的双亲委派类加载机制:JDK核心类库(rt.jar内置的xml相关类)由启动类加载器加载,优先级远高于应用类加载器加载的第三方jar包中的同全限定名类,因此默认情况下项目引入的xml-apis:1.4.01中的类不会被优先加载。
前置检查
先确认pom.xml中xml-apis依赖的scope未设置为provided,确保打包时该jar会被包含到最终的应用包中。
可行解决方案
方案1:JAXP显式指定解析器实现(无侵入,优先推荐)
JAXP(Java XML处理API)支持通过配置指定DocumentBuilderFactory的实现类,无需修改Javadocx的内部代码,有两种配置方式:
- 启动时添加JVM系统参数:
注:xml-apis 1.4.01通常配套xerces实现,需确保项目中已引入对应版本的xerces依赖-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl - 资源文件配置:在项目的
src/main/resources目录下新建META-INF/services/javax.xml.parsers.DocumentBuilderFactory文件,文件内容直接写入要使用的实现类全限定名即可,打包后自动生效。
方案2:使用JDK8的Endorsed目录机制覆盖核心类
JDK8支持Endorsed标准扩展机制,指定目录下的jar会优先于JDK核心类加载:
- 在应用部署目录新建独立文件夹,例如命名为
endorsed,将xml-apis-1.4.01.jar以及配套的xerces实现jar放入该文件夹 - 应用启动时添加JVM参数:
Windows环境下路径格式对应调整即可-Djava.endorsed.dirs=./endorsed
方案3:容器类加载配置(仅适用于War包部署到Tomcat等容器场景)
如果应用是War包部署到Tomcat容器,可修改应用的META-INF/context.xml配置,调整类加载优先级:
<Context> <!-- 关闭默认双亲委派逻辑,优先加载Web应用自身jar包中的类 --> <Loader delegate="false" /> <!-- 可按需配置仅优先加载xml相关包 --> <PreventClassLoaderLocking className="javax.xml.*" /> </Context>
内容的提问来源于stack exchange,提问作者thomas
相关产品推荐
相关产品推荐

