Spring Boot可执行jar包如何正确获取其所在的目录路径?
问题根因
- Spring Boot 可执行jar采用嵌套归档结构,业务类默认存放在jar包内部的
BOOT-INF/classes路径下,通过类的ProtectionDomain获取到的CodeSource路径实际指向的是jar包内部的业务代码路径,因此返回值会携带file:协议前缀以及!/BOOT-INF的内部路径分隔后缀。 - 直接将该字符串传入File构造方法无法识别Spring Boot的嵌套路径规则,因此解析得到的父目录完全不符合预期。
修复实现
可以通过路径裁剪+编码兼容的方式处理,兼容开发环境运行和生产jar运行两种场景,实现代码如下:
import java.io.File; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; public class JarPathUtils { public static String getExecutableJarParentDir() { URL codeSourceUrl = BeanConfig.class.getProtectionDomain().getCodeSource().getLocation(); String jarFullPath; try { // 优先通过URI解析,自动处理URL编码的空格、中文等特殊字符 jarFullPath = new File(codeSourceUrl.toURI()).getAbsolutePath(); } catch (URISyntaxException e) { // 解析异常时兜底手动解码路径 jarFullPath = URLDecoder.decode(codeSourceUrl.getPath(), StandardCharsets.UTF_8); } // 识别Spring Boot嵌套jar的分隔符,裁剪掉jar包内部路径 int jarSeparatorIndex = jarFullPath.indexOf(".jar!/"); if (jarSeparatorIndex > 0) { jarFullPath = jarFullPath.substring(0, jarSeparatorIndex + 4); } // 返回jar文件所在的父目录路径 return new File(jarFullPath).getParentFile().getAbsolutePath(); } }
调用该方法即可拿到你需要的/home/andrea/git/notartel-api-batch/target/路径。
内容的提问来源于stack exchange,提问作者AndreaNobili
相关产品推荐
相关产品推荐

