this.getClass()。getClassLoader()。getResource(“...”)和NullPointerException

问题描述 投票:53回答:8

我在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());

  }

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

我遵循了这个指南:

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

但仍然得到相同的错误。

eclipse maven-2 classloader
8个回答
89
投票

当你使用

this.getClass().getResource("myFile.ext")

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

this.getClass().getResource("/myFile.ext")

getResource会将它视为一个绝对的路径,只需像你所做的那样调用类加载器。

this.getClass().getClassLoader().getResource("myFile.ext")

你不能在/路径中使用领先的ClassLoader的原因是因为所有ClassLoader路径都是绝对的,所以/不是路径中有效的第一个字符。


33
投票

长度,

  • 当您使用.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));
    }
}

输出:

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

18
投票

它应该是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目标。


4
投票

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

  • 资源文件与java源文件位于java源文件夹(src/test/java)中的包中。
  • 我在命令行上使用maven构建项目,并且在使用NullPointerException的测试中构建失败。
  • 命令行构建没有将资源文件复制到test-classes文件夹,这解释了构建失败。
  • 在命令行构建之后进行eclipse并在eclipse中重新运行测试时我也在eclipse中得到了NullPointerException
  • 当我清理项目(删除目标文件夹的内容)并在Eclipse中重建项目时,测试确实正确运行。这解释了为什么它在你开始一个干净的项目时运行。

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

顺便说一下,我用过getClass().getResource(...)


4
投票

当eclipse运行测试用例时,它将在目标/类中查找文件而不是src / test / resources。当资源被保存时,eclipse应该将它从src / test / resources复制到目标/类,如果它已经改变但如果由于某种原因没有发生,那么你将得到这个错误。检查文件是否存在于目标/类中以查看是否存在问题。


1
投票

我想我确实遇到了和你一样的问题。我创建了一个简单的maven项目并使用“mvn eclipse:eclipse”来设置eclipse项目。

例如,我的源文件“Router.java”位于“java / main / org / jhoh / mvc”中。并且Router.java想要读取位于“java / main / org / jhoh / mvc / resources”中的文件“routes”

我在eclipse中运行“Router.java”,eclipse的控制台得到了NullPointerExeption。我使用此设置设置pom.xml以使所有* .class java字节码文件位于构建目录中。

<build>
    <defaultGoal>package</defaultGoal>
    <directory>${basedir}/build</directory>
<build>

我去了目录“build / classes / org / jhoh / mvc / resources”,没有“路线”。 Eclipse DID不将“routes”复制到“build / classes / org / jhoh / mvc / resources”

我认为您可以将“install.xml”复制到* .class字节码目录,而不是源代码目录中。


0
投票

我在使用Maven的项目上遇到了同样的问题。我在这里修理它:我只是将资源(图像,音乐和其他东西)放在资源目录中:

src/main/resources

我也为资源目录中的包创建了相同的结构。例如:

如果我上课了

com.package1.main

在资源目录中,我放了一个具有相同名称的包

com.package1.main

所以我用

getClass().getResource("resource.png");

0
投票

另外一件事就是为我解决了这个问题:

在Eclipse / Maven项目中,我在src/test/java中使用了Java类,其中我使用this.getClass().getResource("someFile.ext");模式在src/test/resources中查找资源,其中资源文件位于资源源文件夹中的相同包位置,因为测试类位于测试源文件夹。它仍然无法找到它们。

右键单击src/test/resources源文件夹,Build Path,然后“配置包含/排除过滤器”;我添加了一个新的**/*.ext包含过滤器,以确保我的文件没有被擦洗;我的测试现在可以找到他们的资源文件。

© www.soinside.com 2019 - 2024. All rights reserved.