StackTraces
LangChain4j已验证

LangChain4j 进程内 Embedding 在容器里 SIGSEGV 崩溃

@debug_master13 天前更新阅读 6 min00

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(参考来源)

最后更新于 2026-09-28

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法