Having an issue loading text files

If it’s working fine in Eclipse and not when running the JAR, then the files you’re trying to load are not being included in the JAR file within a folder called “res”. Is there something you need to do to the folder in Eclipse for this to happen?

It is a critical piece of information. The earlier you share this with people you’re asking for help, the sooner issues get resolved.

It seems like your resource just cannot be found by the InputStream. You have to check if the packages are properly named. Also if you have copied SHC’s code you should check, if youre resources are located in a package called res.:

Have you added the ‘res’ folder to your build path?

Project -> Properties -> Java Build Path -> Source [Tab] -> Add Folder?

In that case omit the “res/” part of the name since, if you take a look at your bin folder, you will see that there is no actual res folder added into the final package. Simply use “/” + name.

You can add an additional folder under the res folder and call it “names” - in that case, you would use “/names/” + name.

I did like SHC said and created a new package called ‘res’ and used explorer to move the files into there. They get exported automatically and the folder and all of the files are present in the exported JAR. When I go to the bin folder, there is a folder called res.

is the ‘res’ folder under the ‘src’ folder? Also package/folder - same thing.

Yeah, this should help to clear things up.

and all the images and .src files are in ‘res’

Personally I would take out the res folder from under “src” and add the “res” folder to the Java Build Path (the src folder is by default already in the Java Build Path).

However, in your case it should work by simply using “/res/resourceName.src”.

Also, you should use the “Reverse Domain Name Notation” http://en.wikipedia.org/wiki/Reverse_domain_name_notation in your “toasted.com” package. I.e, rename it “com.toasted”.

[EDIT]: Also, I like to use the “Navigator” instead of the “Package Explorer” in Eclipse - not that it matters.

It’s working for me. Here’s my structure of eclipse with Space Invaders project.

This is my load image method.


public static Image loadImage(String name)
{
    Image img = null;
    if (cache == null)
    {
        cache = new HashMap < String, Image > ();
    }
    if (cache.containsKey(name))
    {
        img = cache.get(name);
    }
    else
    {
        try
        {
            img = new ImageIcon(Game.class.getClassLoader().getResource(name)).getImage();
            cache.put(name, img);
        }
        catch (Exception e)
        {
            System.err.println("Error loading image : " + name + "\nFatal error. The program is exiting.");
        }
    }
    return img;
}

And I load the images lile


image = loadImage("resources/alien_ship.png");

It works for me perfectly.

@SHC
I’m not having any trouble loading images. They load perfectly fine. However, the trouble is with InputStreams.

@jonjava
So, I moved the ‘res’ folder from ‘src’ and put it alongside the ‘src’ folder. Then I added it to the build path. Images still load fine, but the .src files will not load. The problem has got to be somewhere in this line.

		return Assets.class.getClassLoader().getResourceAsStream("/" + name);

As it is always returning null.

Seems like you’re not getting the classLoader from an instantiated object in which case the “getClassLoader()” will return null iirc. Try changing that to:

 return Assets.class.getResourceAsStream("/" + name);

http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html

The nullPointerException suggests that the InputStream is null. In the Constructor of the InputStreamReader’s superclass Reader you will find this:


if (lock == null) {
      throw new NullPointerException();
}

lock is in that case the InputStream Object created from getResourceAsStream(). This is what getResourceAsStream() returns:


public InputStream getResourceAsStream(String name) {
      URL url = getResource(name);
      try {
            return url != null ? url.openStream() : null;
      } catch (IOException e) {
            return null;
      }
}

So your URL is definetely null. This (as we all know) only happens if your path is not valid.

Ok, so I changed it to:

return Assets.class.getResourceAsStream("/" + name);

and that works fine and dandy in eclipse, but still throws a null pointer when run from a jar.

Yes, indeed, sirkarpfen.

class and ClassLoader are similar and different. Take a look at this stackoverflow post:

try with the ClassLoader without the leading dash:

return Assets.class.getClassLoader().getResourceAsStream(name);

I did as you said, and both worked perfectly in the workspace, but STILL not when i export. I double checked that the files made it into the jar as well.

Is the res folder still in the build-path? if yes, try to remove it, paste it into your source-folder again and try it with the given advices.

Now, quick question, with the res folder in the build path, shouldn’t it automatically take everything from the res folder and drop it into the bin folder?

Yes. There’s no need to put everything inside the src folder. There’s a problem somewhere else. Lemme hack an example program for some “working” code.

Okay, i tried deleting all the images and .src files from the bin folder and when i went to run it, it didn’t automatically put them back.

You shouldn’t ever need to touch anything inside the bin folder yourself. Try refreshing the project. Here’s a test I made and it works fine for me:

http://www.java-gaming.org/user-generated-content/members/54159/testfile.jar

You can unzip the jar file to see what’s inside.

source code:

package com.heartpirates;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.swing.JFrame;
import javax.swing.JTextArea;

public class Main extends JTextArea {

	String text = "";

	public Main() {
		this.setRows(6);
	}

	public void work() throws IOException {
		InputStream is = Main.class.getClassLoader().getResourceAsStream(
				"names.src");
		BufferedReader br = new BufferedReader(new InputStreamReader(is));

		boolean running = true;
		String s = null;
		while (true) {
			s = br.readLine();
			if (s == null)
				break;
			print(s);
		}

		print("Done.");
	}

	private void print(String s) {
		text += s + "\n";
		this.setText(text);
		System.out.println(s);
	}

	public static void main(String[] args) {
		Main m = new Main();
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(m);
		frame.pack();
		frame.setVisible(true);
		
		try {
			m.work();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

OK, I’ve got it now. I’ve got it just how you set it up, jonjava. Also, I had no idea that the string for the name was case sensitive. You people have been a huge help. Thanks so much.