前言
我们在项目中在很多时候需要获取到当前项目的根路径,或者当前执行类的所在路径,进而构建 File 对象。在正常情况下一般都是使用 XX.class.get Resource().getPath(),那么如果我们想要获取该类所处的 jar 包呢,例如我们使用的是第三方引入 jar 包中的类,那么我们该如何获取该类所处 jar 包的绝对路径呢?
1. 获取运行类的绝对路径
使用 Class.getResource().getPath()来获取
下面我们来看看示例
public class Test {
public static void main(String[] args) throws URISyntaxException {
System.out.println(Test.class.getResource("").getPath());
System.out.println(Test.class.getResource(".").getPath());
System.out.println(Test.class.getResource("/").getPath());
}
}
执行结果:
/D:/workspace_demo/springboot-packagejar/target/classes/com/lonely/springbootpackagejar/
/D:/workspace_demo/springboot-packagejar/target/classes/com/lonely/springbootpackagejar/
/D:/workspace_demo/springboot-packagejar/target/classes/
从结果中可以看到,在 getResource("") 和 getResource(".") 都是以指定 Class 类所处位置的绝对路径,而如果是 getResource("/") , 则是获取整个项目运行中的根路径的绝对路径。
2. 获取运行类的所处 jar 包绝对路径
在上面的案例中,我们知道了如何获取指定运行类所处的绝对路径,但是如果这个类是一个第三方的 jar 包,则该路径会进入到该 jar 包中的具体路径中,但是如果我们只想要获取该类处于哪个 jar 包中怎么办,可以使用下面的方法。
下面的代码,是在查看 SpringBoot 源码中以外发现,在源码中看到使用该段代码来加载 class 类和 lib,具体路径在:org.springframework.boot.loader.Launcher#createArchive
Class.getProtectionDomain().getCodeSource().getLocation().toURI().getSchemeSpecificPart();
案例实现:
public class Test {
public static void main(String[] args) throws URISyntaxException {
ProtectionDomain protectionDomain = JarLauncher.class.getProtectionDomain();
CodeSource codeSource = protectionDomain.getCodeSource();
URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null;
String path = (location != null) ? location.getSchemeSpecificPart() : null;
System.out.println(path);
}
}
执行结果:
/D:/workspace_demo/springboot-packagejar/target/springboot-packagejar-0.0.1-SNAPSHOT.jar
针对这个结果,可能有些朋友运行同样的代码会有不一样的结果,下面来分析一波。
- 如果直接将该代码拿到编辑器上,会提示 JarLauncher 类找不到,因为该类实际上是在 SpringBoot 工程打包后,Spring 提供的插件会将一个 jar 包的所有文件内容都放入打好的 jar 包中。而我们如果想要看源码,需要添加依赖,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
</dependency>
- 添加好依赖后,执行上述代码可能结果也不是如上的,可能现在该 jar 是处于自己的本地 maven 仓库中,因为此时,你没有把加入的依赖打入 jar 包中,需要使用命令 ----- mvn clean package 进行打入 jar 包,在执行 jar 包获取结果。