获取运行类的绝对路径和所属jar包

前言

我们在项目中在很多时候需要获取到当前项目的根路径,或者当前执行类的所在路径,进而构建 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 

针对这个结果,可能有些朋友运行同样的代码会有不一样的结果,下面来分析一波。

  1. 如果直接将该代码拿到编辑器上,会提示 JarLauncher 类找不到,因为该类实际上是在 SpringBoot 工程打包后,Spring 提供的插件会将一个 jar 包的所有文件内容都放入打好的 jar 包中。而我们如果想要看源码,需要添加依赖,如下:
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-loader</artifactId> 
</dependency> 
  1. 添加好依赖后,执行上述代码可能结果也不是如上的,可能现在该 jar 是处于自己的本地 maven 仓库中,因为此时,你没有把加入的依赖打入 jar 包中,需要使用命令 ----- mvn clean package 进行打入 jar 包,在执行 jar 包获取结果。
posted @ 2020-08-10 11:48  风中追风_lonely  阅读(2525)  评论(0编辑  收藏  举报