IntelliJ IDEA - getClass().getResource("...") 返回 null

44

我正在使用 IntelliJ IDEA 13.1.5,之前我使用的是 Eclipse。我正在开发一个 JavaFX 应用程序,尝试在 MainApp 类中使用 getClass().getResource() 加载 FXML 文件。我阅读了文档并尝试了几种想法,最终得到了null

这是层次结构:

dz.bilaldjago.homekode.MainApp.java

dz.bilaldjago.homekode.view.RootLayout.FXML

这是我使用的代码片段:

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("view/RootLayout.fxml"));

我尝试了其他的解决方案,例如从根目录提供URL并使用classLoader,但结果是相同的。请问还有什么想法吗?


3
可能重复的问题:Java - class.getResource返回null - maja
请注意,这可能是IntelliJ的一个错误。详细信息请参阅https://youtrack.jetbrains.com/issue/IDEA-119280。- 在这里,所有的测试都能正常工作,但对于真正的运行却不行。我这边的解决方案是将out/production/resources中的所有内容复制到out/production/classes中。 - undefined
15个回答

29

我通过在IDEA中指出资源根目录来解决了这个问题。

右键单击一个目录(或者项目名称)-> 标记目录为 -> 资源根目录

重新编译并欢呼 :P 希望这对你有用~


1
对我没有起作用,我改变了编译器资源模式。将资源文件夹设置为项目的根文件夹,然后是我的类所在的工作文件夹,仍然不起作用!请帮帮我。我正在使用IntelliJ。 - Metin Dagcilar
@AVERAGE 你好,我认为这应该不是问题。你尝试过重新创建一个项目并且重复你的操作吗?如果还是不能解决,请发布你详细的操作步骤,那会有助于解决你的问题。 - MewX
对我而言,如果“src/resources”路径与“src/main”路径相邻,则工作正常;但如果在“resources”路径中,则结果为 null。 - BingLi224
我的示例程序已经开始运行,那个“HELLO”窗口也出现了,但是即使现在错误仍然存在,即->“参数'getClass().getResource("sample.fxml")'可能为空”。 - Just_chill

27

TL; DR;

  1. 把你的资源放在 resources 文件夹里。

  2. 在它们的名字前加一个斜线来使用:getClass().getResource("/myfont.ttf");

Long Story;

如果你正在使用 Intellij IDEA 并且创建了一个 Maven 项目,那么你应该把你的资源放在 resources 文件夹中(如 Intellij 标记为资源根目录),这些资源将会被打包到应用程序的根目录中。

也就是说,/resources/myfont.ttf 将会变成 /myfont.ttf 在最终构建结果中。

因此,你应该使用 /myfont.ttf 而不是 myfont.ttf 来获取资源。使用下面这种方式:

getClass().getResource("/myfont.ttf");

不需要改变其他任何东西,只有这一个帮了我。


2
谢谢,我漏掉了前导斜杠,需要在他们的名字前加上一个斜杠。 - mihca

25

对于使用Intellij Idea的用户,请检查设置 -> 编译器 -> 资源模式

该设置包含应被解释为资源的所有扩展名。如果某个扩展名不符合任何模式,则使用该扩展名的资源将导致class.getResource返回null。


2
我使用模式?*.fxml添加fxml文件,但结果是一样的! - BilalDja
4
没任何变化! - BilalDja
我在Jidea 14.1.1上遇到了同样的问题,更新资源模式后问题得到解决。 :) - Coder
2
@BilalDja,你解决了这个问题吗?因为我现在也遇到了同样的问题。 - Metin Dagcilar
1
我也一样:我遇到了同样的问题,但是我无法解决它。我已经尝试更改资源模式。 - Davide3i
显示剩余3条评论

4

如果你的项目是一个Maven项目,检查目标代码,看看你的.fxml文件是否存在。如果不存在,就添加进去。

<resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>

在您的pom.xml文件中。

1
除了上述提到的方法,如果使用Maven,这是一个关键点。永远不要忘记加载pom.xml文件并在build节点中编写resource节点。 - Sinri Edogawa
同样适用于 Kotlin。 - Raj
它对我起作用了。 看这里: https://maven.apache.org/plugins/maven-resources-plugin/examples/resource-directory.html - chirag soni

4
首先,您需要为IntelliJ设置srcresource文件夹。
请查看java(蓝色)和资源(黄色4行)文件夹旁边的图标。

enter image description here

右键单击 java 文件夹,选择 源根enter image description here 然后右键单击 java 文件夹,选择 资源根enter image description here 之后在 java 文件夹和资源文件夹中创建相同的包。
例如:包 -> org.example enter image description here
├─ src
   ├─ main
       ├─ java
       |  └─ com
       |      └─ example
       |           └─ A.class
       |
       └─ resources  
          └─ com
              └─ example
                    └─ fxml
                         └─ AFXML.fxml

在 A 类中你可以使用这个。Java
 FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/AFXML.fxml"));
 Parent root = loader.load();

科特林

 val loader = FXMLLoader(javaClass.getResource("fxml/AFXML.fxml"))
 val root = loader.load<Parent>()

或者

 val loader = FXMLLoader(A::class.java.getResource("fxml/AFXML.fxml"))
 val root = loader.load<Parent>()

2
非常令人沮丧。另外还会出现包含资源的目录被创建为:
 └── resources
     └── my.tests             
           ├── t1.txt
           └── t2.txt

替代方案:

 └── resources
     └── my
          └── tests
              ├── t1.txt
              └── t2.txt


解决方法就是手动重新创建目录结构,使其类似于第二个示例。
如果您使用Maven,请建议在命令行上进行测试(使用mvn clean test)以消除这可能是IDE问题的可能性。

1
IntelliJ 的另一个陷阱是,如果您按照上述说明创建目录结构,IntelliJ 将自动将其转换为包结构(my.tests)。这发生在 IntelliJ 的默认视图 - 项目视图中。 创建资源目录的唯一方法是切换到“项目文件”视图。只有这样,您才能创建正确的目录结构... - caytekin

2
如果您的项目是Gradle,请检查“设置”->“构建、执行、部署”->“Gradle”->“构建和运行”部分。 确保“使用构建和运行”选项为“Gradle”。
Intellij IDEA的编译器不会将“资源”复制到构建目录或测试类路径中。 此外,它意外地使用虚拟的“out”目录而不是“build”。
更新:只需将“构建和运行使用”选项设置为Gradle即可。

1
在我的情况下,ClassLoader 有所帮助。
Class testClass = getClass();
URL url = testClass.getClassLoader().getResource(/fileName);

你的答案可以通过提供更多支持性信息来改进。请[编辑]以添加更多细节,例如引用或文档,以便他人可以确认您的答案是否正确。您可以在帮助中心中找到撰写好答案的更多信息。 - Community
此外,fileName 的开头不能有 / - koppor

0

我曾经遇到过同样的问题,并尝试了这篇帖子中的所有答案。最终,我在另一个论坛上找到了一个可行的答案。这是我放入pom.xml构建部分的代码:

<resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

确保目录部分是资源类的目录,而不是主类,这一点非常重要。

我还按照另一个评论中的建议更改了编译器设置。 我在这里的帖子中找到了这个答案:https://javawithus.com/en/classloadergetresource-returns-null/


0

根据建议,更新答案。

步骤1

  1. 右键单击项目
  2. 点击标记目录为
  3. 点击源根

步骤2

  1. 在菜单栏中点击文件
  2. 点击项目结构...以打开设置面板

步骤3

  1. 点击模块选项卡
  2. 您会发现没有将任何资源文件夹添加为内容根
  3. 我们需要将资源文件夹添加到其中

步骤4

  1. 确保单击资源文件夹
  2. 然后单击资源选项卡
  3. 您将看到资源文件夹被添加为右侧面板中的资源文件夹

重新运行您的Java程序,现在它应该可以正常工作了。

<---上一个答案---->

今天通过将资源文件夹添加到IntelliJ IDE的资源选项卡中解决了类似的问题

希望这可以帮到你。另外,详细教程

1
谢谢您的回答,我不确定它是否是正确的答案 ;) 在stackoverflow上链接图像并不是一个好的行为。您能描述一下您所做的吗?也许可以用列表样式:1.) 点击这里 2.) 按下按钮 或箭头样式 "资源->编辑" - nologin
1
感谢 @nologin 的建议 - 我是 Stack Overflow 社区的新手。已更新答案。 - user10713884

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接