java.lang.NoClassDefFoundError: javax/xml/stream/XMLStreamException 是經典的「類定義找不到」錯誤,通常發生在運行時而非編譯時。本文針對該異常的兩大核心成因——缺少 jsr173 API 包與JDK 版本不一致——提供具體排查步驟與解決方案,並附帶實戰案例。
NoClassDefFoundError:類在編譯時存在,但在運行時類加載器無法找到該類的定義。javax.xml.stream.XMLStreamException:屬於 StAX (Streaming API for XML) 標準 API,包含在 jsr173_1.0_api.jar 或 JDK 6+ 的 rt.jar 中。JDK 1.5 及之前版本不包含 StAX API,需額外引入 jsr173_1.0_api.jar(及實現如 stax-api-1.0.1.jar、wstx-asl.jar 等)。
<dependency>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
<version>1.0-2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.woodstox</groupId>
<artifactId>woodstox-core</artifactId>
<version>6.4.0</version>
</dependency>
jsr173_1.0_api.jar 放入項目 WEB-INF/lib 或服務器共享庫目錄(如 Tomcat lib/)。maven-compiler-plugin 的 source/target 版本衝突。JAVA_HOME 指向的版本(java -version)。mvn help:effective-pom 查看 maven.compiler.source/target 或 maven-compiler-plugin 配置。pom.xml:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
mvn clean install -U 強制更新快照依賴,清除舊編譯產物。「以前的一個 XFire 項目,今天重新導入後不能運行,修改工程的 JDK 版本不行,最後發現是 Tomcat 環境的 JDK 版本問題。」
分析: XFire 早期 Web Service 框架依賴 StAX API。開發者在 IDE 中將項目 JDK 改為 1.8,但 Tomcat 仍運行在 JDK 1.5/1.6,導致運行時缺少 javax.xml.stream 包(舊版 JDK 需額外 JAR)。統一 Tomcat JDK 至 1.8 後問題即刻解決。
| 步驟 | 操作 |
|---|---|
| 1 | 確認異常類全限定名,搜索 Maven Central 確定所屬 Artifact |
| 2 | 檢查依賴樹:mvn dependency:tree | grep artifactId |
| 3 | 驗證運行時 Classpath:System.getProperty("java.class.path") 或 Arthas classloader -t |
| 4 | 排查類加載器隔離:Web 容器、OSGi、Shade 插件重定向等 |
| 5 | 確認 JDK 版本一致性(編譯/打包/運行/測試) |
NoClassDefFoundError: javax/xml/stream/XMLStreamException 90% 以上由JDK 版本不一致或缺少 StAX API 依賴引發。現代項目(JDK 8+)標準庫已內置 StAX,核心解決之道是統一全鏈路 JDK 版本並清理無效緩存。養成「編譯版本=運行版本」的工程紀律,可避免此類低級錯誤。