Spring 引导:无法使用 lib/*.jar 中的 class 读取 lib/*.jar 中的资源

Spring Boot: Unable to read resources in lib/*.jar using a class in lib/*.jar

我正在使用 spring 引导 org.springframework.boot.loader.JarLauncher 到 运行 我自己的可执行文件 spring 引导应用程序 jar。

现在,我将自己的可执行 jar 打包成这样(为简洁起见,我只添加了显示问题所需的文件):

Main.jar   
      ---META-INF
      ---lib
           ---a.jar
              ---com
                  ---comp
                     ---Abc.class
              ---folder1
                 ---1.txt
                 ---2.txt
           ---b.jar

等等。

在我的 Abc.class 中,我正在尝试加载资源 1.txt,当我在 eclipse 中 运行 它工作正常;但是当我 运行 使用命令行作为自执行 jar 时,故事就开始了。我无法读取该资源并以空指针错误结束。

阅读几篇文章后,我了解到我的 IDE 在 Class 加载器上做了一些魔术,所以它工作正常,当我 运行 它作为可执行 jar

这就是我加载文件的方式以及我尝试过的所有可能的选项,但都没有成功。

选项 1:

Abc.class.getResourceAsStream("\folder1.txt")

选项 2:

Abc.class.getClassLoader().getResourceAsStream("folder1.txt")

选项 3:阅读 thread,我也尝试过考虑当前线程 class 加载程序上下文,但再次失败

Thread.currentThread().getContextClassLoader().getResourceAsStream("folder1.txt")

谁能指点一下。我应该如何编写代码才能读取 jar 中的资源以及同一个 jar 中的 class?

PS:Spring 引导未将 class-路径条目添加到 MANIFEST.MF,如果我必须为此做些什么,我该怎么做?事实上,当 运行 将我的 jar 设置为当前目录时,我尝试了 -cp,但这也没有用

使用 Spring 的 class ClassPathResource 从 class 路径加载文件。

例如,您可以像这样从 classpath:

将文件读入 String
String fileContent = FileUtils.readFileToString(
       new ClassPathResource("folder1" + File.separator + "1.txt").getFile());

只要该文件在 classpath 上,您使用的是哪种构建工具或项目结构都没有关系。

在 Spring 中,访问资源的最佳方式是通过 Resource APIs. For a Classpath resource what you should use a ClassPathResource,它看起来像这样:

Resource resource = new ClassPathResource("/my/resource.json", this.getClass());

获得 Resource 后,您可以通过 getFile() 获得 File 参考,或者通过调用 getInputStream() 直接获得 InputStream

Spring 提供了很多 Resource 接口的不同实现,请查看 docs

中的已知实现列表