Почему метод getResource () возвращает нуль в JDK 11? - PullRequest
0 голосов
/ 03 января 2019

Простая Java-программа:

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();
}

Методы getResource и getResourceAsStream отлично работают в JDK 8 (java-8-openjdk-amd64), но они всегда возвращают null в JDK 11.

Вопросы: почему? И как я могу это исправить?

  • Операционная система: Linux Mint 19 Tara x64
  • IDE: Eclipse 2018-12 (4.10.0)

1 Ответ

0 голосов
/ 03 января 2019

Я пробовал ваше приложение с обоими openjdk 8 и 11 на MacOS, и оно не работает с обоими.Я думаю, вам нужно взглянуть на [1] и [2], чтобы понять, как работает getResourceAsStream.

TLDR:

  1. Если путь абсолютный (т. Е. Начинается с косой черты - /), то class.getResourceAsStream() выполняет поиск по указанному пути

  2. Если путь НЕ абсолютен (то есть не начинается с косой черты), то class.getResourceAsStream() выполняет поиск в построенном пути, соответствующем имени пакета, где точки заменяются косыми чертами

Итак, работает ли он или нет, зависит от 2 вещей:

  1. Является ли ваш путь абсолютным или нет?
  2. Находится ли file в той же упаковке, что и класс, или нет?

По сути, в вашем примере, как указано, он не может работать, если путь не является абсолютным, потому что Class.class.getResourceAsStream() всегда будет разрешать путь к java/lang/<file>, поэтому ваш файл должен находиться в системе.пакет.Поэтому вместо этого вы должны использовать <MyClass>.class.getResourceAsStream() или альтернативно использовать абсолютный путь

[1] https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)

[2] https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource%28java.lang.String%29


Обновление

Начиная с Java SE 9, вызывая getResourceXXX для класса в именованном модуле, только найдет ресурс в этом модуле, он не будет искать путь к классу, как это было в предыдущем выпуске.Поэтому, когда вы используете Class.class.getResourceAsStream(), он попытается найти ресурс в модуле, содержащем java.lang.Class, который является java.base модулем.Очевидно, ваш ресурс не находится в этом модуле, поэтому он возвращает ноль.

Вы должны сделать java 9+ для поиска файла в вашем модуле, который, скорее всего, является "неназванным модулем".Вы можете сделать это, изменив Class на любой класс, определенный в вашем модуле, чтобы заставить java использовать правильный загрузчик классов.

...