UnsupportedClassVersionError是 JVM 的標準報錯。類文件版本比當前 JVM 高,JVM 直接拒絕加載,跟程式碼寫法無關。LangChain4j 1.x 的編譯基線是 JDK 17,把它丟進 Java 8 或 11 跑,第一步加載類就炸。出路只有兩條:升運行環境,或者退回 0.x。
Issue & Env(案發現場與環境)
- 業務場景:老項目跑在 Java 8,直接引入 LangChain4j 1.x 依賴,調模型時啟動就失敗。
- 環境:運行 JDK 8(或 11),依賴 LangChain4j 1.x。鏡像常見
openjdk:8-jdk、openjdk:8-jre。
StackTrace(堆疊日誌)
java.lang.UnsupportedClassVersionError: dev/langchain4j/model/chat/ChatModel has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
這是 JVM 的標準報錯文案。類名會隨實際引用的第一個類而變,不一定正好是 ChatModel。關鍵看兩個數字:
52.0對應 Java 8。55.0對應 Java 11。61.0對應 Java 17。
「compiled by … 61.0」說明這個類是用 JDK 17 編的,「only recognizes … up to 52.0」說明你的 JVM 是 Java 8。
Reproduce(復現程式碼)
用一個 Java 8 的項目引入 1.x:
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
然後寫一行最普通的調用:
ChatModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
程式碼沒問題。編譯器如果是 17,編譯也能過;但運行在 Java 8 的 JVM 上,加載 ChatModel 的瞬間就拋例外。
Root Cause(根因分析)
class file version 是硬門檻
Java 編譯產物裡記錄了一個 class file version,等於編譯它的 JDK 主版本號。JVM 加載類時先比對:自己的版本低於類文件版本,直接拒絕,拋 UnsupportedClassVersionError。這道檢查發生在程式碼執行之前,和你的寫法、依賴用法都沒關係,細節見 JVMS 的 class File Format。
低版本 JDK 編的類能在高版本 JVM 上跑,反過來不行。所以它只在「低 JVM 跑高類文件」時出現。
1.x 的基線是 JDK 17
LangChain4j 1.x 用 JDK 17 編譯,產物的類文件版本就是 61.0;0.x 系列才是 Java 8 基線。把 1.x 的 jar 丟進 Java 8 或 11,必然撞到版本牆。
別和另一類「環境不達標」的坑混了
順帶區分一下。issue #1655 裡,openjdk:8 容器跑進程內 embedding(DJI/ONNX 原生庫)會直接 SIGSEGV,那是原生庫崩潰,連 Java 例外都不是。issue #2836 裡,1.0.0-beta2 在 Android 上也會崩,屬於平臺支持問題。這兩類和 UnsupportedClassVersionError 不是一回事:後者是字節碼版本檢查,前者是運行環境本身不滿足要求。社區說法,截至撰寫時未核實這些 issue 的最終修復版本。
The Fix(解決方案)
首選:把運行環境升到 JDK 17+
項目能升 JDK 的話,改動很小。Maven 編譯設定改成:
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
Docker 基礎鏡像同步換掉:
FROM eclipse-temurin:17-jre
關鍵是編譯用的 JDK 和運行用的 JRE 都到 17。
兜底:退回 0.x 系列
業務確實卡在 Java 8 或 11,只能退回 0.x。但要接受兩件事:一是 0.x 的 API 和 1.x 不同,名字還是 ChatLanguageModel 和 generate;二是 0.x 已不是主線,新 provider 支持更少,長期看是負債。
排查手段
先確認 JVM 版本:
java -version
mvn -v
再直接看 jar 裡類的版本,<jar> 換成你的 jar 路徑:
javap -verbose -cp <jar> dev.langchain4j.model.chat.ChatModel | grep major
輸出 major version: 61 就是 JDK 17 編的。多模塊工程常出現「編譯用 17、運行用 8」的割裂:本地 mvn -v 是 17,CI 或生產容器鏡像卻是 8。兩邊對齊再驗證。
小結
UnsupportedClassVersionError是 JVM 的字節碼版本檢查,跟程式碼無關。- 1.x 基線是 JDK 17(class 61.0),0.x 才是 Java 8 基線。
- 首選升到 JDK 17+,兜底退回 0.x。
- CI 和生產鏡像的 JDK 要對齊,別編譯 17 運行 8。
