【问题标题】:this.getClass().getClassLoader().getResource("...") and NullPointerExceptionthis.getClass().getClassLoader().getResource("...") 和 NullPointerException
【发布时间】:2011-04-17 17:29:30
【问题描述】:

我在 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


    【解决方案1】:

    当你使用

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

    getResource 将尝试查找与包相关的资源。 如果你使用:

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

    getResource 会将其视为绝对路径,并像完成后一样简单地调用类加载器。

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

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

    【讨论】:

    • 原来我团队使用的父pom只包含*.xml和*.properties。现在......为什么这在我的 Windows 工作站上运行我不确定。我什至查看了我的本地 maven 存储库,以验证它与 linux 盒子上的 pom 是否相同。
    • 嗨@AmishDave,您的后续问题(如果您仍需要答案)应作为新问题发布。随意链接回这个问题和/或这个答案,但是在答案中包含后续问题并不是 Stack Overflow 的常规工作方式。谢谢! :-)
    【解决方案2】:

    图尔,

    • 当您使用.getClass().getResource(fileName) 时,它认为 文件名的位置与调用的位置相同 类。
    • 当你使用.getClass().getClassLoader().getResource(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
    

    【讨论】:

    • 我应该怎么做才能从 bin 中的资源文件夹中获取 Maven 资源?我看到即使我运行 Maven 安装,它们也不会出现在那里。但可能我理解错了:)
    【解决方案3】:

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

    【讨论】:

    • 我也试过:this.getClass().getClassLoader().getResource("/install.xml");没有帮助(我所有其他读取资源的项目都不使用“/”前缀,它们工作正常)。我还尝试在父子节点上运行 mvn clean install (从命令行和 eclipse 中),但仍然是同样的问题。当我检查子文件夹时:导航器中的 target/test-classes 视图它是空的 - 猜这很糟糕。
    • 是的,这很糟糕。发布您指定(如果有) 标签的 pom 部分。也许你正在那里做一些 ? mvn install 绝对应该将您的资源文件复制到相应的类中。测试类文件夹。你在使用 M2Eclipse 吗?
    • 我没有触及任何包含/排除语句。我发现了这个:issues.sonatype.org/browse/MNGECLIPSE-823 可能会解决这个问题。我创建了一个新项目,它又可以工作了。
    • 运行 mvn 包对我有用。非常感谢。
    【解决方案4】:

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

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

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

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我想我确实遇到了和你一样的问题。我创建了一个简单的 mvn 项目并使用“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 没有将“路由”复制到“build/classes/org/jhoh/mvc/resources”

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

        【讨论】:

          【解决方案7】:

          我在使用 Maven 进行项目时遇到了同样的问题。 这是我修复它的方法:我只是将源(图像、音乐和其他东西)放在资源目录中:

          src/main/resources
          

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

          如果我的课在

          com.package1.main
          

          在资源目录中我放了​​一个同名的包

          com.package1.main
          

          所以我用

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

          【讨论】:

            【解决方案8】:

            另一件事可以解决我的问题:

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

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

            【讨论】:

              【解决方案9】:

              如果您在 Netbeans(不是 Ant)中使用 Java Maven 项目,则将您的文件按如下方式放置:

              src
                test
                  java
                  resources
                    install.xml
              

              注意resources 文件夹的位置。您还可以在资源中包含嵌套文件夹。然后您可以按以下方式访问您的文件,

              URL url = this.getClass().getResource("/install.xml");
              

              更多详情:https://stackoverflow.com/a/56008648/1942069

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-04-13
                • 1970-01-01
                • 2023-03-21
                • 1970-01-01
                • 1970-01-01
                • 2010-10-12
                • 2013-01-22
                • 1970-01-01
                相关资源
                最近更新 更多