Java ClassLoader.getResourceAsStream(路径) return 当资源在嵌套 jar 中时为 null

Java ClassLoader.getResourceAsStream(path) return null when resource is inside nested jar

我的springboot项目(项目A)依赖库(库B),是jar文件(也是我的项目,但是编译项目A时没有源码)。在罐子里我有一个目录 dir1 和一个文件 file2.

项目结构:

- project A
-- src/main/java/com/test/ResourcesUtils.java
-- src/main/resources/dir1/file1

- library B
-- src/main/resources/dir1/file2

当我尝试从项目 A 获取资源时,一切正常,例如:

InputStream is1 = ResourcesUtils.class.getClassLoader().getResourceAsStream("dir1\file1);
InputStream is2 = ResourcesUtils.class.getClassLoader().getResourceAsStream("dir1/file1);

两个 (is1, is2) 都不为空。

当我尝试使用相同的方法从图书馆 B 获取资源时,它不起作用

InputStream is1 = ResourcesUtils.class.getClassLoader().getResourceAsStream("dir1\file2);
InputStream is2 = ResourcesUtils.class.getClassLoader().getResourceAsStream("dir1/file2);

变量 is1 为空,is2 不为空。

我做错了什么吗?为什么主 jar 资源与从属 jar 资源的工作方式不同?

我不能只切换到第二个版本(使用“/”,因为我没有控制传递给 getResourceAsStream 的字符串)

public static boolean existsInResource(Path path) {

try (InputStream is = ResourcesUtils.class.getClassLoader().getResourceAsStream(path.toString())) {
      return is != null;
    } catch (final IOException e) {
      // handle exception
    }
  }

当提到 file1, 时,它是您应用程序中的一个物理文件,我假设您 运行 您的代码在 Windows 上。文件 file1 在 Windows 文件系统中。

当引用 file2 时,它在一个 JAR 文件中。那不是 windows 文件系统,它是一个 JAR 文件。

除非您知道该文件是物理文件,否则使用正斜杠更安全。 \ 是 Windows NT 之前的旧 32 位 windows 的残基。 Windows NT里面(不知道没记错)使用/,命令处理器只使用\.