Java如何获取通过软链接执行jar时对应的软链接路径而非实际路径
问题原因
你当前使用的getProtectionDomain().getCodeSource().getLocation()接口,底层会自动解析所有符号链接返回文件的真实物理路径,所以不可能通过这个接口拿到软链接路径。
解决方法
软链接路径是你执行jar时传入的路径/当前工作目录属性,需要从进程启动参数/工作目录获取,分两种常见场景处理:
场景1:先cd到软链接目录再执行jar
执行命令示例:
cd C:\SoftLink1 java -jar MyJar.jar
这种情况直接获取JVM的当前工作目录即可,user.dir属性不会自动解析软链接,会返回你cd进入的软链接路径:
// 代码实现 String softLinkDir = System.getProperty("user.dir"); String jarFullPath = softLinkDir + "\\MyJar.jar"; System.out.println(jarFullPath); // 输出示例:C:\SoftLink1\MyJar.jar 或 C:\SoftLink2\MyJar.jar
场景2:直接传入软链接全路径执行jar
执行命令示例:
java -jar C:\SoftLink1\MyJar.jar
这种情况需要从进程的完整命令行中提取-jar参数后的路径内容:
Java 9及以上版本
用官方提供的ProcessHandleAPI直接获取命令行:
import java.util.Optional; public class GetSoftLinkPath { public static void main(String[] args) { Optional<String> jarPathOpt = ProcessHandle.current().info().commandLine() .map(commandLine -> { String[] cmdSegments = commandLine.split(" "); for (int i = 0; i < cmdSegments.length; i++) { if ("-jar".equals(cmdSegments[i]) && i + 1 < cmdSegments.length) { return cmdSegments[i + 1]; } } return null; }); jarPathOpt.ifPresent(System.out::println); // 输出示例:C:\SoftLink1\MyJar.jar 或 C:\SoftLink2\MyJar.jar } }
Java 8版本
可以通过调用系统命令获取当前进程的命令行,Windows环境示例:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.lang.management.ManagementFactory; public class GetSoftLinkPath { public static void main(String[] args) throws Exception { // 获取当前进程PID String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; // 执行wmic命令获取命令行 Process process = Runtime.getRuntime().exec("wmic process where ProcessId=" + pid + " get CommandLine"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; String commandLine = ""; while ((line = reader.readLine()) != null) { if (!line.isBlank() && !line.startsWith("CommandLine")) { commandLine = line.trim(); break; } } // 提取-jar后的路径 String[] cmdSegments = commandLine.split(" "); String jarPath = null; for (int i = 0; i < cmdSegments.length; i++) { if ("-jar".equals(cmdSegments[i]) && i + 1 < cmdSegments.length) { jarPath = cmdSegments[i + 1]; break; } } System.out.println(jarPath); } }
注意事项
- 上述方法仅适用于目录符号链接/文件符号链接的场景,Windows下的.lnk快捷方式不属于符号链接,需要单独解析快捷方式文件内容才能获取路径。
- 如果需要同时兼容两种执行场景,可以优先尝试提取命令行中的jar路径,提取失败再用工作目录拼接jar文件名的方式获取。
内容的提问来源于stack exchange,提问作者Vasu
相关产品推荐
相关产品推荐

