Gradle构建的Jar运行时找不到libs目录下Jar包如何解决
问题根源
IDEA内直接运行项目时,程序默认工作目录是项目根目录,与libs文件夹所处层级匹配,因此硬编码的相对路径libs/procyon-0.6.0.jar可以正常定位到文件。
Gradle构建生成可执行Jar后,单独运行时的工作目录是用户执行java -jar命令时所处的目录,且构建流程默认不会将项目根目录下的libs文件夹同步到Jar产物的同级目录,自然无法命中对应路径。
操作步骤
完全满足无额外启动参数、不依赖-classpath/-cp、常规java -jar启动的要求,按以下两步配置即可:
- 配置Gradle构建逻辑,构建时自动将依赖的
libs目录复制到产物同级位置
如果使用Gradle原生jar任务构建可执行包,在build.gradle中添加如下配置,原有主类声明等配置保留即可:
如果使用Shadow等插件打胖包,将上述复制逻辑挂载到对应构建任务的jar { // 原有manifest等配置无需改动 doLast { copy { from 'libs' into "${buildDir}/libs/libs" } } }doLast生命周期即可,最终要保证构建输出的主程序Jar所在文件夹下,存在libs/procyon-0.6.0.jar的层级结构。 - 代码中动态获取procyon Jar的绝对路径,不要硬编码相对路径
避免用户在非Jar所在目录执行启动命令时,因工作目录变化导致路径失效,在Main.java中通过主类加载位置获取Jar所在目录,再拼接procyon的路径:import java.io.File; import java.net.URISyntaxException; public class Main { public static void main(String[] args) throws URISyntaxException { // 获取主程序Jar自身所在的目录 File jarHome = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile(); // 拼接procyon Jar的绝对路径 String procyonPath = new File(jarHome, "libs/procyon-0.6.0.jar").getAbsolutePath(); // 执行对应命令 String command = String.format("java -jar %s --arguments", procyonPath); try { Runtime.getRuntime().exec(command); } catch (Exception e) { e.printStackTrace(); } } }
部署时只要保持主程序Jar和同级
libs目录的结构不被破坏,无论在哪个系统路径下执行主程序的启动命令,都能正常定位到procyon的Jar文件,不需要添加任何额外启动参数。
内容的提问来源于stack exchange,提问作者SynnK
相关产品推荐
相关产品推荐

