Jlink无法推导模块描述符及模块找不到问题排查与解决
解决Jlink创建独立可执行文件的两个常见问题
咱们一步步来拆解你遇到的两个jlink相关错误:
一、初始错误:Unable to derive module descriptor for ./out/hello-app.jar
错误含义
Jlink是Java 9+专为模块化Java应用打造的工具,它只能处理包含module-info.class(模块描述符)的JAR文件。你最开始的Hello World JAR是传统的非模块化JAR——根本没有模块描述符,jlink没法识别它的模块信息,自然就抛出这个错误了。
初始错误的核心修复方向
要用上jlink,必须先把你的应用转换成模块化JAR,核心就是添加module-info.java并完成正确的编译打包。
二、新错误:Error: Module hello not found
错误原因
你已经添加了module-info.java,但出现这个问题大概率是两个原因之一:
- 编译好的模块化JAR没被放到
--module-path指定的路径下,jlink找不到名为hello的模块; - 编译过程没正确生成包含
module-info.class的有效模块化JAR,导致模块不被识别。
完整可执行的修复步骤
下面是从源码到生成独立镜像的完整操作流程,你可以跟着走一遍:
- 确认源码结构(和你当前的结构一致即可)
src/ ├── hello │ └── Main.java └── module-info.java
建议给module-info.java加上包导出(因为要执行Main类,方便模块识别):
module hello { exports hello; }
Main.java保持你的代码即可:
package hello; public class Main { public static void main(final String[] args) { System.out.println("Hello, world. "); } }
- 编译模块化源码
用javac的模块化编译命令,把编译后的类文件输出到out目录:
javac -d out src/module-info.java src/hello/Main.java
执行完后,out目录会有正确的结构:
out/ ├── module-info.class └── hello └── Main.class
- 打包成模块化JAR
把out下的内容打包成带模块信息的JAR,顺便指定主类(方便后续运行):
jar --create --file hello-app.jar --main-class hello.Main -C out .
你可以用这个命令验证JAR是否是模块化的:
jar --describe-module --file hello-app.jar
输出里应该能看到模块hello的详细信息。
- 用jlink生成独立镜像
现在执行jlink命令,注意--module-path要包含你的模块化JAR,还要加上JDK的jmods目录(如果系统没自动识别的话):
jlink --module-path $JAVA_HOME/jmods:hello-app.jar --add-modules hello --output testout
如果你的JDK在默认路径,也可以简化成:
jlink --module-path hello-app.jar --add-modules hello --output testout
- 运行生成的独立镜像
进入输出目录的bin文件夹,执行启动命令:
# 方式一:指定模块和主类 ./testout/bin/java -m hello/hello.Main # 方式二:因为打包时指定了主类,直接指定模块即可 ./testout/bin/java -m hello
额外提醒
- 如果你用
$(location :hello-app)这种变量,一定要确认它的值是hello-app.jar的正确路径,不然jlink还是找不到模块; - 确保编译、打包、jlink用的是同一个版本的JDK(你这里是10.0.1,没问题),版本不一致很容易出奇怪的问题。
内容的提问来源于stack exchange,提问作者sdgfsdh
相关产品推荐
相关产品推荐

