Why Java cannot read same resource file when module-info is added?(为什么Java在添加MODULE-INFO时无法读取相同的资源文件?)
问题描述
有一个简单的Java项目,具有标准的Maven文件夹结构。
src
main
java
mypackage
Main.java
resource
abc
cde.txt
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
}
此代码运行良好,可以从绝对路径读取文件
"%project_root%/target/classes/abc/cde.txt"
(编译代码)。
添加文件src/main/java/module-info.java
后,情况发生变化:程序找不到该文件并引发in branch (input == null)
。
"src/main/resources"
。
推荐答案
您可能需要这个:
InputStream input = Main.class.getResourceAsStream("/abc/cde.txt");
当您添加模块-info.java时,Java会将您的类视为module。
模块的封装限制超出了普通旧类路径的限制。若要访问模块中的资源,其他代码必须通过该模块,该模块将检查调用代码的模块是否具有读取这些资源的权限。ClassLoader.getResourceAsStreamwill only read resources from explicitly opened modules:
附加…此方法仅在无条件打开命名模块的包时查找该包中的资源。
但Class.getResource和Class.getResourceAsStream仅依赖于类所属的模块,并且没有该附加限制。
应始终使用Class.getResource或Class.getResourceAsStream。应避免使用ClassLoader等效项。Class方法和ClassLoader方法之间有一个重要的区别:Class方法将参数视为相对于类的包,除非参数以斜杠(/
)开头。
除了封装限制外,给定一个名为com.example.MyApplication的类,这两行代码是等价的:
MyApplication.class.getResource("data.txt")
MyApplication.class.getClassLoader().getResource("com/example/data.txt")
并且这些是等效的:
MyApplication.class.getResource("/data.txt")
MyApplication.class.getClassLoader().getResource("data.txt")
同样,它们只是在资源路径方面是等价的;模块化封装限制不相同。始终使用Class.getResource*方法,避免使用ClassLoader.getResource*方法。
这篇关于为什么Java在添加MODULE-INFO时无法读取相同的资源文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么Java在添加MODULE-INFO时无法读取相同的资源文件?
基础教程推荐
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01