使用 dom4j 的 XPath 查詢方法(selectNodes、selectSingleNode、valueOf)時,拋出 java.lang.NoClassDefFoundError: org/jaxen/JaxenException。本文解析錯誤根因、依賴關係與 Maven/Gradle 修正方案。
java.lang.NoClassDefFoundError: org/jaxen/JaxenException
at org.dom4j.DocumentFactory.createXPath(DocumentFactory.java:230)
at org.dom4j.tree.AbstractNode.createXPath(AbstractNode.java:207)
at org.dom4j.tree.AbstractNode.selectNodes(AbstractNode.java:164)
...
Caused by: java.lang.ClassNotFoundException: org.jaxen.JaxenException
關鍵點:DocumentFactory.createXPath() 內部實例化 Jaxen XPath 引擎,屬於 dom4j 可選依賴,未隨 dom4j 主包傳遞。
dom4j (核心)
└── 可選依賴 → jaxen (XPath 引擎)
└── 需顯式引入
selectNodes、selectSingleNode、numberValueOf 等方法首次調用時觸發 Class.forName("org.jaxen.XPath")。jaxen.jar,即拋 NoClassDefFoundError。<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.4</version> <!-- 或 1.6.1 -->
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version> <!-- 必須顯式引入 -->
</dependency>
dom4j 2.x 建議搭配 jaxen 1.2.0+;dom4j 1.x 兼容 jaxen 1.1.6。
implementation 'org.dom4j:dom4j:2.1.4'
implementation 'jaxen:jaxen:1.2.0'
jaxen-1.2.0.jar(Maven Central 搜尋)。WEB-INF/lib 或應用伺服器共享庫目錄。| 現象 | 原因 | 解決 |
|---|---|---|
| 引入 jaxen 後仍報錯 | 版本衝突(多版本 jaxen 共存) | mvn dependency:tree 排除傳遞依賴,統一版本 |
| WebLogic/WebSphere 內建舊版 jaxen | 類載入器優先載入容器舊版 | 設定類載入器策略為 PARENT_LAST 或打包 Fat JAR |
| 僅使用 DOM API 不用 XPath | 誤以為 dom4j 全功能內建 | 不調用 selectNodes 等方法可不引入 jaxen |
若不願引入額外依賴,JDK 內建 javax.xml.xpath 可滿足基本需求:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(inputStream);
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
Node node = (Node) xpath.evaluate("//featureMember", doc, XPathConstants.NODE);
NodeList list = (NodeList) xpath.evaluate("//featureMember", doc, XPathConstants.NODESET);
element.getStringValue() 等)。jaxen:jaxen 依賴即可解決。ClassLoader 優先順序與容器內建庫。