首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么getResource()方法在JDK 11中返回null?

为什么getResource()方法在JDK 11中返回null?
EN

Stack Overflow用户
提问于 2019-01-03 11:52:12
回答 2查看 9.4K关注 0票数 10

简单Java程序:

代码语言:javascript
复制
public static String loadText(String file) {
    StringBuilder finalString = new StringBuilder();

    InputStream in = null;
    BufferedReader reader = null;
    InputStreamReader isr = null;

    try{
        System.out.println("Text File: " + file);

        // Version 1
        //URL url = Thread.currentThread().getClass().getResource(file); 
        //in = url.openStream();

        // Version 2
        in = Class.class.getResourceAsStream(file);

        isr = new InputStreamReader(in);
        reader = new BufferedReader(isr);
        String line;
        while((line = reader.readLine()) != null) {
            finalString.append(line).append("//\n");
        }
    }
    catch(IOException e) {
        e.printStackTrace();
        System.exit(-1);
    }
    finally {
        try {
            if (isr != null) { isr.close(); }
            if (reader != null) { reader.close(); }
            if (in != null) { in.close(); }
            } catch (IOException e) { e.printStackTrace(); }
        }
    return finalString.toString();
}

getResourcegetResourceAsStream方法在JDK 8(java-8-OpenJDK-AMD 64)中运行良好,但它们总是在JDK 11中返回null

问题:为什么?我怎么才能解决这个问题?

  • 操作系统: Linux 19 Tara x64
  • 2018-12日食(4.10.0)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-03 12:20:46

我已经在MacOS上尝试过openjdk 8和11的应用程序,但两者都不能使用。我认为您需要查看1和2,以了解getResourceAsStream是如何工作的。

TLDR:

  1. 如果路径是绝对的(即以斜杠-/开头),则class.getResourceAsStream()在提供的路径中搜索。
  2. 如果路径不是绝对的(即不以斜杠开头),则class.getResourceAsStream()在与包名相对应的构造路径中搜索,其中点被用斜杠替换。

因此,它是否起作用取决于两件事:

  1. 你的道路是绝对的还是没有?
  2. file是否与类位于同一个包中?

基本上,在您提供的示例中,如果路径不是绝对的,则它永远无法工作,因为Class.class.getResourceAsStream()总是解析到java/lang/<file>的路径,因此您的文件必须位于系统包中。因此,您必须使用<MyClass>.class.getResourceAsStream(),或者使用绝对路径。

1

2

更新

因为Java 9在命名模块中的类上调用getResourceXXX只会找到该模块中的资源,所以它不会像以前版本那样搜索类路径。因此,当您使用Class.class.getResourceAsStream()时,它将尝试在包含java.lang.Class的模块(即java.base模块)中定位资源。显然,您的资源不在该模块中,因此它返回null。

您必须让java 9+搜索模块中的文件,这很可能是一个“未命名模块”。您可以通过将Class更改为模块中定义的任何类来做到这一点,以便使java使用正确的类加载器。

票数 19
EN

Stack Overflow用户

发布于 2020-08-12 09:03:24

还有一种使用ClassLoader的解决方案

代码语言:javascript
复制
ClassLoader.getSystemResourceAsStream(file)

所有地点的货物。我使用它从JAR文件中加载资源,JAR文件只包含资源,没有可执行代码,所以前面的技巧无法工作,因为JAR中没有SomeClass来执行SomeClass.class.getResourceAsStream()

我只是不明白内部结构,我也必须改变文件的路径。

我在JAR存档的根目录中有带有"my-file.txt“文件的JAR文件。

对于java 8来说,这是可行的。

代码语言:javascript
复制
Class.class.getResourceAsStream("/my-file.txt");

对于java 11,即使文件位于根路径,我也必须删除前面的/

代码语言:javascript
复制
ClassLoader.getSystemResourceAsStream("my-file.txt");
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54021754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档