最近工作查到了一个有意思的问题,在这里记录一下。
1. 问题背景
Java应用 SAP 系统自带了一个 jre,但在Ubutnu2004上部分功能不正常。
初步排查发现,该 JRE 版本来源不明(用户也说不清是哪里来的)。
于是尝试以下方案:
-
替换 JRE:从 Ubuntu 2004 launchpad 下载
openjdk-21-jre
的 deb 包,解压后将其jre
目录替换 SAP 自带的 JRE。 -
测试失败:替换后应用报错
NoClassDefFoundError: Could not initialize class sun. launcher. LauncherHelpersResourceBundleHolder
,但若在系统中安装apt install openjdk-21-jre
,则不会出现此问题。
2. 排查过程
为什么原本有问题的SAP在安装了openjdk-21-jre之后就正常了?
经排查发现,直接解压 deb 包的 jre
目录中存在大量的软链接,其指向的路径(如 /usr/lib
)在独立环境中不存在,导致依赖丢失,因此SAP启动报错。
改用Adoptium Temurin 的 JRE,其 JRE 是真正的自包含发行版,所有依赖均以硬拷贝或相对路径形式存在,无外部软链接依赖,替换后解决问题。
3. 技术原理:OpenJDK 发行版的两种设计哲学
3.1. 系统级发行版(如 Ubuntu OpenJDK)
-
目标:与 Linux 发行版深度集成。
-
特点
-
文件遵循 Linux 文件系统层级标准(FHS)分散在
/usr/lib/jvm
、/usr/bin
、/usr/share
等标准路径。 -
通过软链接实现多版本共存和默认版本切换。
-
不适合直接拷贝:脱离默认环境后,软链接失效。
-
3.2. 独立发行版(如 Adoptium Temurin)
-
目标:提供“开箱即用”的二进制,无外部依赖。
-
特点
-
所有文件(包括库、配置文件)集中在单一目录。
-
无绝对路径软链接,通过相对路径或硬编码实现自包含。
-
适合嵌入应用:可直接打包到容器或应用目录中。
-