如何在Java9中使用类加载器访问资源

如何在Java9中使用类加载器访问资源,java,javafx,classloader,java-9,Java,Javafx,Classloader,Java 9,我在eclipse中有一个gradle项目。这是我的项目结构 我在scr/main/resources/css中有css资源styleclass.css。首先,我尝试使用 scene.getStylesheets().add("css/styleclass.css"); String urlString = ComboBoxStyling.class.getClassLoader().getResource("css/styleclass.css").toExternalForm();

我在eclipse中有一个gradle项目。这是我的项目结构

我在
scr/main/resources/css
中有css资源
styleclass.css
。首先,我尝试使用

scene.getStylesheets().add("css/styleclass.css"); 
String urlString = ComboBoxStyling.class.getClassLoader().getResource("css/styleclass.css").toExternalForm();
但是我得到了一个警告:未找到
资源。
我还通过删除
module info.java
文件进行了尝试。但结果是一样的

然后我试着用

scene.getStylesheets().add("css/styleclass.css"); 
String urlString = ComboBoxStyling.class.getClassLoader().getResource("css/styleclass.css").toExternalForm();
问题是,如果我删除
moduele info.java
并应用样式表,这一行就可以工作。但是使用
module info.java
我得到了空指针异常

我知道的不多,但至少我知道类加载器在Java9中有变化。那么我如何在Java9中实现同样的功能呢。我的
module info.java
文件包含以下内容

module pk.training.basit {
    exports pk.training.basit;
    requires transitive javafx.controls;
}
谢谢和问候


Basit Mahmood Ahmed

来自
ClassLoader.getResource
JavaDoc:

命名模块中的资源受Module.getResourceAsStream指定的封装规则约束。此外,除了资源的名称以“.class”结尾的特殊情况外,当无条件打开包时,此方法仅在命名模块的包中查找资源(即使此方法的调用方与资源位于同一模块中)

因此,要解决您的问题,您应该打开包
css

module pk.training.basit {
    exports pk.training.basit;
    requires transitive javafx.controls;
    opens css;
}

您应该将css与使用它的类放在同一个包中,然后使用class.getResource以相对路径访问它

src/main/java:
  pk.training.basit
    ComboBoxStyling.java

src/main/resources:
  pk.training.basit
    ComboBoxStyling.css
然后在来源中:

scene.getStylesheets().add(
  ComboBoxStyling.class.getResource("ComboBoxStyling.css").toExternalForm());

就个人而言,我认为将css和类放在同一个目录中,然后配置gradle,这样它就可以获取src/main目录中的资源,这是更好的做法。它允许使用类似于其他GUI产品(Angular)的架构,将屏幕的所有资源(包括源代码)放在同一目录中,例如FXML文件(如果有)。

资源被封装,因此无法使用ClassLoader API找到。我假设ComboboxStyleing.class..getResource(“/css/styleclass.css”)将起作用-请注意前导斜杠,以便它相对于模块的根位置找到,在本例中与ComboxStyleing.class无关。是的,这就是工作:)@Alan Bateman发布您的答案,这样我就可以接受了最初的问题似乎是代码试图找到自己的资源。ClassLoader API在这方面是错误的API。如果代码更改为在模块中的类上调用getResource,那么它应该可以正常工作,无需打开任何包。@AlanBateman我只需准确回答OP的问题。如果他有200个带有
getClassLoader().getResource()
的位置怎么办?因此,他可以只添加一行代码,而不是更改这200个位置。