this.getClass().getClassLoader().getResource("...")和NullPointerException

u12*_*123 57 eclipse maven-2 classloader

我在eclipse helios中创建了一个带有单个子模块的最小maven项目.

在src/test/resources文件夹中,我放了一个文件"install.xml".在文件夹src/test/java中,我创建了一个包含单个类的包:

  @Test
  public void doit() throws Exception {
    URL url = this.getClass().getClassLoader().getResource("install.xml");
    System.out.println(url.getPath());

  }
Run Code Online (Sandbox Code Playgroud)

但是当我将代码作为junit 4单元测试运行时,我只得到一个NullPointerException.这之前已经运行了数百万次.有任何想法吗?

我遵循了这个指南:

http://www.fuyun.org/2009/11/how-to-read-input-files-in-maven-junit/

但仍然得到相同的错误.

Ami*_*ave 93

当你使用

this.getClass().getResource("myFile.ext")
Run Code Online (Sandbox Code Playgroud)

getResource将尝试查找相对于包的资源.如果您使用:

this.getClass().getResource("/myFile.ext")
Run Code Online (Sandbox Code Playgroud)

getResource 将它视为一个绝对的路径,并简单地调用类加载器就像你已经完成的那样.

this.getClass().getClassLoader().getResource("myFile.ext")
Run Code Online (Sandbox Code Playgroud)

您不能/ClassLoader路径中使用前导的原因是因为所有ClassLoader路径都是绝对路径,因此路径中/的有效第一个字符不是.

  • 嗨@AmishDave,你的后续问题(如果你还需要一个答案)应该作为一个新问题发布.请随意链接回这个问题和/或这个答案,但在答案中有一个后续问题并不是传统上Stack Overflow的工作方式.谢谢!:-) (2认同)

nam*_*olk 36

TUL,

  • 当您使用.getClass().getResource(fileName)它时,认为fileName的位置与调用类的位置相同.
  • 当你使用.getClass().getClassLoader().getResource(fileName)它时,认为fileName的位置是根 - 换句话说 bin文件夹.

资源 :

package Sound;
public class ResourceTest {
    public static void main(String[] args) {
        String fileName = "Kalimba.mp3";
        System.out.println(fileName);
        System.out.println(new ResourceTest().getClass().getResource(fileName));
        System.out.println(new ResourceTest().getClass().getClassLoader().getResource(fileName));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Sound/Kalimba.mp3
file:/C:/Users/User/Workspaces/MyEclipse%208.5/JMplayer/bin/Kalimba.mp3
Run Code Online (Sandbox Code Playgroud)


mha*_*ler 19

它应该是 getResource("/install.xml");

资源名称是相对的getClass()班所在之处,例如,如果你的测试org/example/foo/MyTest.class,然后getResource("install.xml")将查找org/example/foo/install.xml.

如果您install.xmlsrc/test/resources,它位于类路径的根目录中,因此您需要在其前面添加资源名称/.

此外,如果它只是有时工作,那么可能是因为Eclipse已经清理了输出目录(例如target/test-classes),并且资源只是从运行时类路径中丢失了.验证使用Eclipse的Navigator视图而不是Package explorer.如果文件丢失,请运行mvn package目标.


Hil*_*amp 5

我在以下情况下遇到了同样的问题:

  • 资源文件与Java源文件位于Java源文件夹(src/test/java)中相同的软件包中。
  • 我在命令行上使用maven生成了项目,而在使用的测试中生成失败NullPointerException
  • 命令行构建未将资源文件复制到文件test-classes夹,这说明了构建失败。
  • 当在命令行构建后执行eclipse并在eclipse中重新运行测试时,我也获得了NullPointerExceptioneclipse。
  • 当我清理项目(删除目标文件夹的内容)并在Eclipse中重建项目时,测试确实可以正常运行。这解释了为什么当您从一个干净的项目开始时它会运行。

我通过将资源文件放在测试中的resources文件夹中src/test/resources来解决此问题:使用与源类相同的包结构。

我用的顺便说一句 getClass().getResource(...)


oen*_*lli 5

当eclipse运行测试用例时,它将在target / classes而不是src / test / resources中查找文件。保存资源后,eclipse应该将它从src / test / resources复制到目标/类(如果已更改),但是如果由于某种原因没有发生,则会出现此错误。检查目标/类中是否存在该文件,以查看是否存在此问题。