InputStream.getResourceAsStream()给出空指针异常

Cod*_*Med 3 java inputstream

该行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);
    }  
Run Code Online (Sandbox Code Playgroud)

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

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");
Run Code Online (Sandbox Code Playgroud)

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

这是eclipse项目目录结构的打印屏幕.调用包含该方法的类TestFunctions.java,并显示其位置persistence.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);
}  
Run Code Online (Sandbox Code Playgroud)

我还将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  
Run Code Online (Sandbox Code Playgroud)

chi*_*ity 5

两件事情:

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

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

try {
    // some stuff
} catch (IOException ignored) {}
Run Code Online (Sandbox Code Playgroud)

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

但此刻,你只是在地毯下扫地.


Sbo*_*odd 5

简短答案:将persistence.properties移至src / main / resources,在src / main / java中同时包含Main.java和TestFunctions.java,并使用

 getClass().getClassLoader().getResourceAsStream("persistence.properties");
Run Code Online (Sandbox Code Playgroud)

加载属性文件。

长答案,并附有解释:

正如其他人所暗示的那样-在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则TestFunctions和persistence都可以。