Search code examples
javainputstream

InputStream.getResourceAsStream() giving null pointer exception


The line persistenceProperties.load(is); is throwing a nullpointerexception in the following method. How can I resolve this error?

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);
    }  

I have tried to experiment with this by moving the class that contains the method to various other locations within the application structure, and also by changing the line of code preceding the error in the following ways:

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");

But the error is still thrown every time the method is called.

Here is a printscreen of the directory structure of the eclipse project. The class containing the method is called TestFunctions.java, and the location of persistence.properties is shown:


**EDIT: **

As per feedback below, I changed the method to:

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);
}  

I also moved mainTest.TestFunctions.java to src/test/java. Together, these all cause the following new stack trace:

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  

Solution

  • Short answer:

    • Move persistence.properties to src/main/resources
    • Have both Main.java and TestFunctions.java in src/main/java
    • and use getClass().getClassLoader().getResourceAsStream("persistence.properties");

    to load the properties file.

    Long answer with an explanation:

    As others have hinted at, in a Maven project structure, you (typically) have two directory trees:

    • /src/main
    • /src/test

    The general intent is that any "real" code, resources, etc should go in /src/main, and items that are test-only should go in /src/test. When compiled and run, items in the test tree generally have access to items in the main tree, since they're intended to test the stuff in main; items in the main tree, however, do not typically have access to items in the test tree, since it's generally a bad idea to have your "production" code depending on test stuff. So, since Main.java depends on TestFunctions.java, and TestFunctions.java depends on persistence.properties, if Main is in src/main then both TestFunctions and persistence.properties need to be as well.