-1

I keep getting a java.lang.NullPointerException when trying to open a txt file in eclipse. Basically, this is a main menu, and when you click the "Rules" button, the rules text file should open. Currently, the txt file is located in a package called "Resources" (which is where all of the other img files I've used in making the game are). Here's the code:

private List<String> readFile(String filename)
{
  List<String> records = new ArrayList<String>();
  try
  {
    BufferedReader buff = new BufferedReader(new InputStreamReader(
            Configuration.class.getResourceAsStream(filename)));
    String line;
    while ((line = buff.readLine()) != null)
    {
      records.add(line);
    }
    buff.close();
    return records;
  }
  catch (Exception e)
  {
    System.err.format("Exception occurred trying to read '%s'.", filename);
    e.printStackTrace();
    return null;
  }
}

//action performed
public void actionPerformed(ActionEvent ae) {
    JButton b = (JButton)ae.getSource();
    if( b.equals(newGameButton) )
        {
        flag = true;
        controller.startGame();
        buttonPressed = "newGameBtn";
        }
    if(b.equals(quitButton))
    {
        System.exit(0);
    }
    if(b.equals(ruleButton)){
        readFile("../resource/riskRules.txt");
    }

}

Appreciate the help!

user2938241
  • 35
  • 2
  • 8
  • please show your stacktrace – Scary Wombat Apr 16 '15 at 00:56
  • @ErwinBolwidt This is a null pointer exception but the root cause is very specific. – Tim Biegeleisen Apr 16 '15 at 01:03
  • @TimBiegeleisen How can you tell? there is nothing specific in the question. It doesn't even mention where the exception occurs. The duplicate helps to explain how to work with stack traces, which seems to be a good place to begin for the OP. "Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime" – Erwin Bolwidt Apr 16 '15 at 01:50
  • @user2938241 Please review the answers and attempt to solve your problem. – Tim Biegeleisen Apr 16 '15 at 01:53

2 Answers2

1

If "Resources" it's marked as resource in Eclipse. The txt file should be copied to your class path when you build. As per what I can guess from your code you should be doing something like

Configuration.class.getResourceAsStream("riskRules.txt")

Since your file will be at the root level of your class path.

If for example the file is withing a dir called "text" in your resources you would use something like

Configuration.class.getResourceAsStream("text/riskRules.txt")
pablorc
  • 472
  • 1
  • 4
  • 11
0

There needs to be some level of rudimentary error checking on the result returned from getResourceAsStream before you attempt to use it. Is there a reason you're using getResourceAsStream instead of getResource? If the file exists on disk (I see from your OP that it's because it's in a package, and may not physically exist on the disk), then you can just use that to return the path to it, and create a file object from it.

String path = "/path/to/resource"; // note the leading '/' means "search from root of classpath"
URL fileUrl = getClass().getResource(path);
if (fileUrl != null ) {
    File f = new File(fileUrl.toURI());
    BufferedReader = new BufferedReader(new FileReader(f));
    // do stuff here...
}
else {
    // file not found...
}

If you need to pull the file out of the JAR archive, then you can do this:

String path = "/path/to/resource"; // note the leading '/' means "search from root of classpath"
InputStream is = getClass().getResourceAsStream(path);
if (is != null ) {
    BufferedReader = new BufferedReader(new InputStreamReader(is));
    // do stuff here...
}
else {
    // file not found...
}

In the event your resource is not found, you will avoid the NPE and you can properly account for the fact that it's missing.

Note that if you do have your resources in a package (jar), then you cannot use a path to locate it that uses "..", since there is no "relative path" in a jar archive, it's not actually a file on the filesystem.

Your "resources" are located by the relative path you specify in the getResource... method. A leading "/" means to look at the root of your classpath for locating the resource. No leading "/" means to look relative to the location of the class file that you're using to locate the resource.

If your file is in a location called "com.program.resources", and you're trying to locate it from a class called "com.program.someotherpackage.MyClass", then you'd use:

getClass().getResourceAsStream("/com/program/resources/<file.txt>");

to find it.

Here's my example illustrated:

<classpath root>
      com
           program
                resources
                     file.txt
                     img.png
                someotherpackage
                     MyClass.class

Generally, it's common practice to leave resources outside your package structure, to avoid confusion when locating them later. Most IDE's have a way to mark your directories as resources, so when the program is compiled, they will be copied to the proper location in the classpath root, and can be found by any class asking for them.

Ryan J
  • 8,275
  • 3
  • 25
  • 28