为什么添加 module-info 后 Java 无法读取相同的资源文件?

diz*_*iaq 1 java resources classloader java-module

有一个具有标准 Maven 文件夹结构的简单 Java 项目。

src
  main
    java
      mypackage
        Main.java
    resource
      abc
        cde.txt  
Run Code Online (Sandbox Code Playgroud)

Main.java(省略样板)

var path = "abc/cde.txt";
InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);

if (input == null) {
    throw new IllegalStateException("Resource not found");
} else {
   // read from input
}
Run Code Online (Sandbox Code Playgroud)

该代码工作正常并从绝对路径
"%project_root%/target/classes/abc/cde.txt"(编译后的代码)读取文件。

添加文件后src/main/java/module-info.java情况发生变化:程序找不到文件并抛出in branch (input == null)

如何以旧方式从“资源”文件夹中读取文件并同时拥有:资源文件夹中的java模块和资源?我想避免"src/main/resources"到处添加前缀。

VGR*_*VGR 7

你可能想要这个:

\n
InputStream input = Main.class.getResourceAsStream("/abc/cde.txt");\n
Run Code Online (Sandbox Code Playgroud)\n

当您添加 module-info.java 时,Java会将您的类视为模块。

\n

模块的封装限制超出了普通旧类路径的限制。要访问模块中的资源,其他代码必须经过该模块,该模块将检查调用的 code\xe2\x80\x99s 模块是否有权读取这些资源。

\n

ClassLoader.getResourceAsStream只会从显式打开的模块中读取资源

\n
\n

另外,\xe2\x80\xa6 仅当无条件打开包时,此方法才会在指定模块的包中查找资源。

\n
\n

但是Class.getResourceClass.getResourceAsStream仅依赖于该类所属的模块,并且 don\xe2\x80\x99t 有额外的限制。

\n

应始终使用 Class.getResource 或 Class.getResourceAsStream。应避免使用 ClassLoader 等价物。

\n

Class 方法和 ClassLoader 方法之间有一个重要区别:Class 方法将参数视为相对于 class\xe2\x80\x99s 包,除非参数以斜杠 ( /) 开头。

\n

除了封装限制之外,给定一个名为 com.example.MyApplication 的类,这两行是等效的:

\n
MyApplication.class.getResource("data.txt")\nMyApplication.class.getClassLoader().getResource("com/example/data.txt")\n
Run Code Online (Sandbox Code Playgroud)\n

这些是等效的:

\n
MyApplication.class.getResource("/data.txt")\nMyApplication.class.getClassLoader().getResource("data.txt")\n
Run Code Online (Sandbox Code Playgroud)\n

同样,它们仅在资源路径方面是等效的;模块化封装限制一样。始终使用 Class.getResource* 方法,并避免使用 ClassLoader.getResource* 方法。

\n

  • 值得一提的是,原始代码更糟糕,通过使用“Thread.currentThread().getContextClassLoader()”,它根本不能保证是“MyApplication.class.getClassLoader()”(或任何知道“MyApplication”的加载器) 。即使在 Java 9 之前,这种情况也可能会在很多方面受到破坏。 (2认同)