1. 程式人生 > >Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found 問題排查

Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found 問題排查

缺少 pcl fall api 自帶 new load delet caused

自定義的classLoader啟動spring容器,遇到
Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not subtype (classpath下有類)

Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found(classpath下沒有類)
兩個異常信息。

這個問題比較詭異,缺少包和沒有包都有問題,有包的情況下報 not subtype(這個應該是classLoader之間的問題,直接調整類的加載策略為雙親委派策略,問題解決),沒包的情況報 not found。只能走上排查之路了。
先根據堆棧進入到源碼,

Caused by: javax.xml.parsers.FactoryConfigurationError: Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found
at javax.xml.parsers.DocumentBuilderFactory.newInstance(Unknown Source)
at com.ibatis.common.xml.NodeletParser.createDocument(NodeletParser.java:165)
at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:59)
at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.parse(SqlMapConfigParser.java:62)
at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.parse(SqlMapConfigParser.java:55)
at org.springframework.orm.ibatis.SqlMapClientFactoryBean.buildSqlMapClient(SqlMapClientFactoryBean.java:338)
at org.springframework.orm.ibatis.SqlMapClientFactoryBean.afterPropertiesSet(SqlMapClientFactoryBean.java:291)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1648)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1585)
... 38 common frames omitted

xml的解析工具在實例化的時候出現了錯誤,比較奇怪的是,其他使用了相同框架的模塊並不會出現這個問題。先打開日誌輸出的參數,在jvm的啟動參數中增加 -Djaxp.debug=true

這個參數打開之後,可以輸出 DocumentBuilderFactory 在實例化時會使用哪個具體的實現類去實例化。


JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: loaded from fallback value: com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
JAXP: created new instance of class com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl using ClassLoader: null

JAXP: find factoryId =javax.xml.parsers.SAXParserFactory
JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl using ClassLoader: null

正常的情況下,會優先使用你的配置類。你可以在 systemProperty中配置具體使用哪個類。如果沒有配置,會使用 com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl 的實現類,是jdk8中自帶的實現類。

默認的 fallback類為:com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
註意這一小段代碼,在classpath下尋找fallback類,如果沒有找到,使用默認的fallback類,這個自動在包中搜索的,所以只要你的包中有相關的實現類,就會被加載並且實例化。

// Try Jar Service Provider Mechanism
T provider = findServiceProvider(type);
if (provider != null) {
return provider;
}

那問題其實已經很明確了,在classpath目錄下找找是不是有相關的類,將相關的依賴包排除掉即可。

<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>

<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>

都讓它使用默認的Factory類。排除掉之後,問題解決。

Provider org.apache.xerces.jaxp.DocumentBuilderFactoryImpl not found 問題排查