You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何jlink生成的启动器在Linux下无法通过符号链接运行?

解决jlink启动器在Linux符号链接下无法运行的问题

我之前也踩过这个坑!这本质是jlink生成的原生启动器在路径解析上的特性导致的——它默认依赖自身所在的实际文件目录来定位配套的JRE模块和应用资源,但当你用软链接(symbolic link)指向启动器时,启动器会误把链接的路径当成自己的位置,从而找不到真实目录下的依赖文件。

先复盘下你的场景(方便其他同学参考)

你的Gradle jlink任务大概是这样的:

task createRuntimeImage(type: Exec) {
    commandLine 'jlink', 
        '--module-path', "build/libs/:${System.getenv('JAVA_HOME')}/jmods", 
        '--add-modules', 'com.your.module', 
        '--output', 'build/image'
}

创建符号链接的操作:

# 假设你把启动器链接到系统bin目录
ln -s ~/your-project/build/image/bin/rawhttp /usr/local/bin/rawhttp

运行时遇到的错误:

Error: Could not find or load main module com.your.module
Caused by: java.lang.module.FindException: Module com.your.module not found

核心原因

jlink生成的shell启动器脚本里,通常会用dirname "$0"来获取自身所在目录,但$0在软链接场景下会指向链接文件的路径(比如/usr/local/bin/rawhttp),而不是启动器实际所在的~/your-project/build/image/bin/,导致启动器找不到该目录下的../lib等资源目录。

三种可行解决方案

1. 修改jlink生成的启动器脚本

找到build/image/bin/rawhttp这个shell脚本,找到获取目录的那一行:

DIR=$(dirname "$0")

替换成能解析软链接真实路径的代码:

# 解析软链接指向的真实文件路径
REAL_PATH=$(readlink -f "$0")
DIR=$(dirname "$REAL_PATH")

这样启动器就能正确定位到它实际所在的目录,不管你用软链接还是硬链接都能正常工作。

2. 使用硬链接代替软链接

硬链接直接指向文件本身,不会有路径解析的问题,创建命令去掉-s参数即可:

ln ~/your-project/build/image/bin/rawhttp /usr/local/bin/rawhttp

注意:硬链接只能在同一文件系统下创建,如果你的项目目录和/usr/local/bin不在同一个分区,这个方法不适用。

3. 创建软链接时使用绝对路径(并确保目标路径正确)

很多时候出错是因为创建软链接时用了相对路径,导致链接指向的路径不正确。确保你用绝对路径创建链接:

# 先确认启动器的绝对路径
realpath ~/your-project/build/image/bin/rawhttp
# 然后用这个绝对路径创建链接
ln -s /full/absolute/path/to/rawhttp /usr/local/bin/rawhttp

这样启动器在解析路径时,能通过链接找到真实的文件位置。

验证方法

修改后运行以下命令检查:

# 检查链接指向的真实路径
readlink -f $(which rawhttp)
# 尝试启动应用
rawhttp

内容的提问来源于stack exchange,提问作者Renato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:58:44