Сбой загрузки классов в подкаталоге с модульным JavaFX

Я сделал проект Gradle, который использует загрузчик классов для загрузки текстового файла из подкаталога resources / text. На данный момент это работает, но когда я преобразую проект в модульную программу JavaFX, та же функция загрузчика классов дает исключение NullPointerException.

src / основной каталог проекта

└───src
    └───main
        ├───java
        │   │   module-info.java
        │   └───app
        │           Main.java
        └───resources
            └───text
                    words.txt

build.gradle

plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version Ɔ.0.8'
}

sourceCompatibility = 11

repositories {
    jcenter()
}

javafx {
    version = ཉ.0.1'
    modules = [ 'javafx.controls']
}

mainClassName = 'exMod/app.Main'
jar {
    manifest {
        attributes 'Main-Class': mainClassName
    }
}

module-info.java

module exMod {
    requires javafx.controls;
    exports app;
}

Main.java

package app;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Main extends Application {

    public static void main(String[] args){ launch(); }

    public void start(Stage stage){
        stage.setTitle("Hello World!");
        Button button = new Button();
        Label label = new Label();
        button.setText("Click me!");
        button.setOnAction(event -> label.setText(getWords()));

        VBox root = new VBox();
        root.setAlignment(Pos.CENTER);
        root.getChildren().addAll(button, label);
        stage.setScene(new Scene(root, 300, 250));
        stage.show();
    }

    private String getWords(){
        String path = "text/words.txt";
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
        InputStreamReader isReader = new InputStreamReader(inputStream); // null exception
        BufferedReader reader = new BufferedReader(isReader);
        StringBuilder content = new StringBuilder();
        try {
            String line;
            while( (line = reader.readLine()) != null) {
                content.append(line);
            }
        } catch(IOException e){
                e.printStackTrace();
        }
        return content.toString();
    }
}

Если я изменяю переменную пути на «words.txt» и перемещаю текстовый файл на один уровень вверх до src / main / resources, это работает, но по причине, которую я не смог обнаружить, загружая файл из подкаталога ресурса не будет работать. Что вызывает исключение NullPointerException и как я могу это исправить?

Всего 1 ответ


В комментарии к этому вопросу в качестве альтернативы program.class.getClassLoader().getResource("b/text.txt") пользователь Хольгер заявляет

... вы должны использовать program.class.getResource("b/text.txt") , чтобы разрешить ресурс относительно расположения класса программы. В противном случае, это может привести к сбою в Java 9 или новее, если вы используете модули, так как переход к загрузчику классов уничтожит информацию о реальном модуле.

Из-за этого я попытался использовать только getClass().getResourceAsStream(path) вместо getClass().getClassLoader().getResourceAsStream(path) .

Я также прочитал комментарий Алана Бейтмана по этому вопросу, где он заявляет

Ресурс инкапсулирован, поэтому его нельзя найти с помощью API ClassLoader. Я предполагаю, что ComboBoxStyling.class..getResource ("/ css / styleclass.css") будет работать - обратите внимание на начальную косую черту, так что она находится относительно корневого расположения модуля , а не относительно ComboBoxStyling.class в этом случае.

Так что мне довелось попробовать эту комбинацию вместе, и она сработала!

getWords ()

private String getWords(){
        String path = "/text/words.txt";
        InputStream in = getClass().getResourceAsStream(path);
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        StringBuilder content = new StringBuilder();
        try {
            String line;
            while( (line = reader.readLine()) != null) {
                content.append(line);
            }
        } catch(IOException e){
                e.printStackTrace();
        }
        return content.toString();
    }

Есть идеи?

10000