AllMiniLmL6V2EmbeddingModel这类进程内模型,靠 DJL + ONNX Runtime 加载原生库在 JVM 里跑推理。容器里直接 SIGSEGV 崩掉,不是 Java 异常,是 native 层执行挂了。先升 JDK 17、换 temurin 镜像,再查原生库依赖链。
Issue & Env(案发现场与环境)
- 环境:Spring Boot 2.2.5 + langchain4j + PostgreSQL pgvector。
- 现象:本地 IDEA 里
AllMiniLmL6V2EmbeddingModel跑得好好的,放进openjdk:8基础镜像的容器就崩,JVM 直接退出。问题来自 langchain4j issue #1655。
StackTrace(堆栈日志)
issue #1655 原文:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fdb638dd4fd, pid=6, tid=0x00007fdad21ae700
#
# JRE version: OpenJDK Runtime Environment (8.0_342-b07) (build 1.8.0_342-b07)
# Java VM: OpenJDK 64-Bit Server VM (25.342-b07 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libc.so.6+0x15b4fd]
#
# Core dump written. Default location: //core or core.6
#
# An error report file with more information is saved as:
# //hs_err_pid6.log
关键两行:SIGSEGV (0xb) 和 Problematic frame: C [libc.so.6+0x15b4fd]。崩在 native 栈上,业务代码的 try/catch 拦不住。
Reproduce(复现代码)
复现要点:进程内 embedding 模型 + openjdk:8 基础镜像。
FROM openjdk:8
COPY app.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
启动后用 AllMiniLmL6V2EmbeddingModel 生成向量,JVM 直接崩,留下 hs_err_pid*.log。
Root Cause(根因分析)
AllMiniLmL6V2EmbeddingModel这类进程内模型,靠 DJL + ONNX Runtime 在 JVM 内跑推理,必须加载随平台分发的原生库(.so/.dll)。这条路不经过 Java 的异常体系:原生库加载或执行失败时,会直接把进程打挂,报的是hs_err_pid*.log,不是Exception。Problematic frame: C [libc.so.6+...]说明崩在 native 栈,业务代码拦不住。相关机制可参考 DJL ONNX Runtime engine 文档。- 触发条件有两层。一是运行环境过老:这里是 Java 8,而 LangChain4j 1.x 的基线是 JDK 17,见 Getting Started。二是容器里原生库的加载与依赖链不完整。
- DJL 官方文档提到,onnxruntime 1.21+ 在部分 JDK 发行版上有冲突,会报
UnsatisfiedLinkError。实测 temurin17 与 zulu17 可用。 - 关键区别:日志或构建期报
UnsatisfiedLinkError,是「原生库没找到」;SIGSEGV是「找到了但执行时崩了」。后者更难查。
The Fix(解决方案)
先把 JDK 升到 17+,基础镜像换成 eclipse-temurin:17-jre:
FROM eclipse-temurin:17-jre
COPY app.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
这一条同时解决「基线不符」和「老 JDK 在容器里的原生库兼容性差」。
- JDK 发行版优先选 temurin 或 zulu。换发行版后 SIGSEGV 变成
UnsatisfiedLinkError,说明前进了一步,原生库至少可见了。继续查架构(x86_64 还是 arm64)与 glibc 依赖。 - 排查路径:找到
hs_err_pid*.log,看Problematic frame与Dynamic libraries段。确认基础镜像的 libc 与 onnxruntime 预期是否匹配。centos7 这类老 glibc 镜像常见GLIBCXX_x.x.x not found。 - 代价更小的替代:容器里不用进程内模型,改用远程 embedding API,或把 embedding 拆成独立服务,别把 native 依赖塞进业务镜像。
- 关联提示:SEGV 出现在 Java 8 上,本质上和「LangChain4j 1.x 需要 JDK 17」是同一类环境问题,只是表现不同。
小结
- SIGSEGV 是 native 层崩溃,不走 Java 异常体系,
hs_err_pid*.log才是第一现场。 - 先升 JDK 17、换
eclipse-temurin:17-jre,再查原生库依赖链。 UnsatisfiedLinkError是库没找到,SIGSEGV是执行时崩,后者更难查。
References(参考来源)
- Application crashes on using AllMiniLmL6V2EmbeddingModel in docker with openjdk:8 — langchain4j issue #1655github-issue
- In-process embedding models — LangChain4j 官方文档langchain4j-docs
- ONNX Runtime engine — DJL 官方文档official-docs
- Getting Started(JDK 基线)— LangChain4j 官方文档langchain4j-docs
