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。
