getClassLoader().getResourceAsStream()在模块化java项目(openjdk 11)



这是一个maven项目,在资源目录中有一个映像:

├─ src
├─ main
├─ java
└─ resources  
└─imgs
└─logo.png

代码:

public class Test {
public static void main(String[] args) {
InputStream stream = Test.class.getClassLoader().getResourceAsStream("/imgs/logo.png");
InputStream stream1 = Test.class.getClassLoader().getResourceAsStream("imgs/logo.png");
System.out.println(stream == null ? "stream is null!" : "stream is not null!");
System.out.println(stream1 == null ? "stream1 is null!" : "stream1 is not null!");
}
}

当我module-info.java添加到项目中时,将打印:

stream is null!
stream1 is null!

但当我从项目中删除module-info.java时,将打印:

stream is null!
stream1 is not null!

为什么?以及如何在模块化java项目中使用ClassLoader加载资源?

资源应该通过Test.class加载,而不是通过其ClassLoader加载。通过在类上加载资源,可以为资源所在的位置建立上下文(JAR、模块、依赖项(。

对于同一软件包中的资源,请使用相对路径:

Test.class.getResource("logo.png")

如果Test的限定名称是org.foo.Test,那么它将在JAR中的org/foo/logo.png中查找资源(或者在构建JAR之前,在resources文件夹中(。

对于同一模块中的资源,请使用绝对路径,以斜杠开头:

Test.class.getResource("/logo.png")

^这是你大多数时候想要使用的。

没有必要遍历类加载器。当开发人员不知道如何正确地寻址资源,并通过类加载器加载具有相对路径的资源时,我经常会看到这种情况,类加载器在大多数情况下都能工作,但在Java9和OSGI等模块化项目/类加载器中效果不太好。

最新更新