当前位置: 首页 > 知识库问答 >
问题:

子目录类装入在模块化 JavaFX 时失败

壤驷心思
2023-03-14

我做了一个Gradle项目,它使用类加载器从子目录资源/text加载文本文件。此时它可以工作,但当我将项目转换为模块化JavaFX程序时,相同的类加载器函数会给出NullPointerException。

└───src
    └───main
        ├───java
        │   │   module-info.java
        │   └───app
        │           Main.java
        └───resources
            └───text
                    words.txt
plugins {
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.8'
}

sourceCompatibility = 11

repositories {
    jcenter()
}

javafx {
    version = '13.0.1'
    modules = [ 'javafx.controls']
}

mainClassName = 'exMod/app.Main'
jar {
    manifest {
        attributes 'Main-Class': mainClassName
    }
}
module exMod {
    requires javafx.controls;
    exports app;
}
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();
    }
}

如果我将path变量更改为“words.txt ”,并将文本文件向上移动一级到src/main/resources,它可以工作,但是由于我无法发现的原因,从资源子目录加载文件将不起作用。是什么导致了NullPointerException,如何修复它?

共有1个答案

吴凯泽
2023-03-14

在对此问题的注释中,作为< code > program . class . get class loader()的替代。getResource(" b/text . txt ")用户Holger声明

…您应该使用<code>program.class.getResource(“b/text.txt”)

正因为如此,我试图只使用getClass(). getResourceAsStream(path)而不是getClass(). getClassLoader(). getResourceAsStream(path)

我也读过艾伦·贝特曼对这个问题的评论,他说

资源是封装的,因此无法使用类加载器 API 找到它。我假设ComboBoxStyling.class..getResource(“/css/styleclass.css”) 将起作用 - 请注意前导斜杠,以便相对于模块的根位置找到它,而不是相对于ComboBoxStyling.class在这种情况下。

所以我碰巧一起尝试了这个组合,果然奏效了!

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();
    }
 类似资料:
  • 本文向大家介绍meteor 导入/模块目录结构,包括了meteor 导入/模块目录结构的使用技巧和注意事项,需要的朋友参考一下 示例 流星的最新版本支持ecmascriptES6或ES2015。Javascript现在支持import语句和模块,而不是软件包,从而取代了仅用于软件包的应用程序。最新的目录结构类似于仅打包的结构,但是使用/imports目录代替/packages。          

  • 我得到了一个多层次的maven项目,如下所示; 在web-app模块中,我有core.jar和service.jar的依赖关系。 有没有办法通过parent在web-app中生成war文件?当我尝试在web-app中运行mvn安装时。我遇到了core.jar和Web服务jar依赖问题。也就是说。我必须先在父项目中运行mvn install,然后在web-app项目中运行mvn war:war?

  • 我尝试在子模块中导入kotlin: 项目级别 模块级

  • 项目模块化 在企业项目中,包层次和类关系比较负责,把代码拆分成模块是一个比较困难的任务,因为这需要你清晰的划分功能的边界,比如把业务逻辑和数据持久化拆分开来。 解耦和聚合 但你的项目符合高内聚低耦合时,模块化就变得很容易,这是一条非常好的软件开发实践。一个很好的模块化的例子就是Spring框架,spring框架提供了很多服务,比如MVC web框架、事务管理器、JDBC数据库连接等,下图展示了Sp

  • 假设我有3个模块:mod1、mod2和mod3。 在正常情况下,文件系统层次结构应为: 但我想要的是: 如何在Android Studio 1.1.0中做到这一点? PS:我发现这篇文章,但它似乎不起作用,或者它适用于AS的早期版本,而不是1.1.0:如何在子目录中移动模块?

  • 问题内容: 我有一个存储所有.py文件的目录。 我想从使用类user.py和dir.py在main.py。 如何将这些Python类导入main.py? 此外,如果user.py在子目录中,如何导入类? 问题答案: Python 2 在与文件相同的目录中创建一个名为的空文件。这将向Python表示“可以从此目录导入”。 然后做… 如果文件位于子目录中,则也应如此-将子目录也放入子目录中,然后使用带