【问题标题】:InputStream.getResourceAsStream() giving null pointer exceptionInputStream.getResourceAsStream() 给出空指针异常
【发布时间】:2014-10-13 19:24:51
【问题描述】:

persistenceProperties.load(is); 行在以下方法中抛出 nullpointerexception如何解决此错误?

public void setUpPersistence(){

    final Properties persistenceProperties = new Properties();
    InputStream is = null;
    try {
        is = getClass().getClassLoader().getResourceAsStream("src/test/samples/persistence.properties");
        persistenceProperties.load(is);
    }catch (IOException ignored) {}
    finally {
        if (is != null) {try {is.close();} catch (IOException ignored) {}}
    }

    entityManagerFactory = Persistence.createEntityManagerFactory(
        "persistence.xml", persistenceProperties);
    }  

我已经尝试通过将包含该方法的类移动到应用程序结构中的各个其他位置来对此进行试验,并且还通过以下方式更改错误之前的代码行:

is = getClass().getClassLoader().getResourceAsStream("persistence.properties");
is = getClass().getClassLoader().getResourceAsStream("/persistence.properties");
is = getClass().getClassLoader().getResourceAsStream("/src/test/samples/persistence.properties");
is = getClass().getClassLoader().getResourceAsStream("other/paths/after/moving/persistence.properties");

但是每次调用该方法时仍然会抛出错误。

这是 eclipse 项目目录结构的打印屏幕。包含该方法的类称为TestFunctions.javapersistence.properties 的位置如图所示:


**编辑:**

根据下面的反馈,我将方法更改为:

public void setUpPersistence(){
    final Properties persistenceProperties = new Properties();
    InputStream is = null;
    try {
        is = getClass().getClassLoader().getResourceAsStream("persistence.properties");
        persistenceProperties.load(is);
    }catch (IOException i) {i.printStackTrace();}
    finally {
        if (is != null) {try {is.close();} catch (IOException ignored) {}}
    }
    entityManagerFactory = Persistence.createEntityManagerFactory(
        "persistence.xml", persistenceProperties);
}  

我还将 mainTest.TestFunctions.java 移至 src/test/java。总之,这些都会导致以下新的堆栈跟踪:

Exception in thread "main" java.lang.NoClassDefFoundError: maintest/TestFunctions
    at maintest.Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: maintest.TestFunctions
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 1 more  

【问题讨论】:

  • is 如果导致异常,则必须为 null。你用调试器找出原因了吗?
  • 你有没有明确的类Properties的无参数构造函数?如果有,请发布。
  • 您能尝试清理并重建您的项目吗?当您将 TestFunctions 移动到 src/test/java 但继续从 src/main/java 引用它时,该项目甚至不应该是可编译的......
  • 无关注意事项:考虑使用 try-with-resources 来关闭您的流。
  • @Puce 这个问题现在已经解决了。谢谢你的见解。我仍在尝试让 hbm2ddl 在 MySQL 数据库中创建表。 create-drop 没有做这项工作。您使用 hbm2ddl 吗?这是链接:stackoverflow.com/questions/26348480/…

标签: java inputstream


【解决方案1】:

简短回答: 将persistence.properties 移动到src/main/resources,在src/main/java 中同时拥有Main.javaTestFunctions.java,并使用

 getClass().getClassLoader().getResourceAsStream("persistence.properties");

加载属性文件。

详细的解释:

正如其他人所暗示的那样 - 在 Maven 项目结构中,您(通常)有两个目录树:/src/main/src/test。一般的意图是任何“真正的”代码、资源等都应该放在/src/main 中,而仅供测试的项目应该放在/src/test 中。在编译和运行时,test 树中的项目通常可以访问main 树中的项目,因为它们旨在测试 main 中的内容;但是,main 树中的项目通常无法访问 test 树中的项目,因为根据测试内容使用“生产”代码通常不是一个好主意。所以,由于Main.java 依赖于TestFunctions.java,而TestFunctions.java 依赖于persistence.properties,如果Main 在src/main 中,那么TestFunctionspersistence.properties 也需要同时存在。

【讨论】:

    【解决方案2】:

    两件事:

    首先,尝试test/samples/.../test/samples/...的路径

    其次,更重要的是,永远不要这样写:

    try {
        // some stuff
    } catch (IOException ignored) {}
    

    这就是说:做一些事情,如果出了问题,那么默默地失败这绝不是正确的做法:如果有问题,你想知道它,而不是像什么都没发生一样疯狂地冲过去。要么在你的 catch 块中做一些合理的处理,要么没有 try/catch 并在你的方法签名中添加一个 throws IOException 以便它可以向上传播。

    但目前,你只是在地毯下扫地。

    【讨论】:

    • @CodeMed 现在看起来它正在正确读取持久性文件,但您的持久性文件指定了一个不存在的类。
    • @CodeMed 听起来您报告的问题现已修复!调试其余部分听起来像是一个新问题,带有相当不同的标签等。
    • @CodeMed 好吧,这完全取决于问题所在!但听起来像 persistencehibernatejava 会是一个好的开始。
    • @CodeMed 不,它们不是同一个问题。空指针异常来自未找到属性文件,现在已修复。您发布的任何代码都无法生成类未找到异常,除了属性文件被解析和分析的位。问题出在某个地方,这是一个不同的问题(由于空指针异常,您直到现在还没有遇到)。
    【解决方案3】:

    ClassLoader.getResourceAsStream() 加载资源就像加载类一样。因此,它从运行时类路径加载它们。不是来自项目中的源目录。

    你的类Main在包maintest中,因此它的名字是maintest.Main。我什至没有看到代码就知道,因为Main.java 位于名为maintest 的目录下,该目录直接位于源目录下。

    persistence.properties 文件直接位于源目录 (src/test/resources) 下。因此,在运行时,它位于类路径的根目录中,在默认包中。因此,它的名称是 persistence.properties,而不是 src/test/samples/peristence.properties。所以代码应该是

     getClass().getClassLoader().getResourceAsStream("persistence.properties");
    

    从示例目录中无法加载任何内容,因为该目录不在任何源目录下,因此不被 Eclipse 编译,因此对 ClassLoader 不可用。

    【讨论】:

    • 你在我上面的原始帖子中看到is = getClass().getClassLoader().getResourceAsStream("persistence.properties"); 也抛出了同样的错误吗?
    【解决方案4】:

    您的 IDE 使用两种不同的范围:

    • 生产范围:src/main/java + src/main/resources 文件夹和
    • 测试范围:src/test/java + src/test/resources

    似乎您正试图从生产范围执行您的程序,而 persistence.properties 文件被放置在测试范围内。

    如何解决:

    • 将测试放入 src/test/java 或
    • 将 persistence.properties 移至 src/main/resources

    【讨论】:

      【解决方案5】:

      我会尽量让这个问题变得更简单!

      这里你的主类在src/main/java中,正如你提到的,所以你应该创建另一个源来存储你的属性文件,说你已经完成的src/main/resources,并将你的属性文件存储在这个源中,所以在运行时它将直接引用此路径并访问该文件,

      您也可以添加这段代码来访问属性文件

      is = ClassLoader.getSystemResourceAsStream("your_properties_file");

      你可以相应地使用load(is)

      总结

      如果您的main 类在src/main/java 中,那么您应该将属性文件保存在src/main/resources 中并使用相应的sn-p 来加载它。

      如果您的main 类在src/test/java 中,那么您应该将属性文件保存在src/test/resources 中并使用相应的sn-p 来加载它。

      【讨论】:

        【解决方案6】:

        InputStream is = this.getClass().getResourceAsStream("/package_name/property 文件名")

        PropertyFileOject.load(is)

        在我的情况下,错误是由于 maven 没有将 src/main/java 中的配置文件夹视为源文件夹。

        在 src/main/java 中重新创建配置包 ..将文件复制到其中并使用 maven 重新编译。文件在目标目录中,因此在战争中。错误已解决。

        【讨论】:

          【解决方案7】:

          我最近遇到了同样的问题,并找到了解决方案,即我必须将资源放在与 getClass().getResourceAsStream(name) 所在位置相同的组织方式中。这样做之后我仍然遇到问题。后来,我发现创建一个包 org.smth.smth 只创建了一个名为“org.smth.smth”的文件夹,而不是一个文件夹 org,其中有一个文件夹 smth 和一个文件夹 smth... 所以创建相同的路径结构解决了我的问题。希望这个解释是可以理解的。

          【讨论】:

            猜你喜欢
            • 2014-09-06
            • 2014-07-19
            • 2017-01-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多