Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does Java put resource files when I JAR my program?

Been looking for this for the past 2 hours and can't find anything (I've found solutions to the same problem but with images, not text files).

Pretty much, I made a program that reads a text file. The file is a list of names and IDs. Using Eclipse, I put the file in my src folder and in the program put the path file to it. Like this:

in = new BufferedReader(new FileReader(curDir+"\\bin\\items.txt"));

Where curDir is the user's current directory (found with System.getProperty("user.dir")).

Now, problem is, the program runs fine when I run it from Eclipse, but when I try to make it a runnable JAR and then run it, the program runs, but the info from the text file does not load. It look like Eclipse is not putting the text file with the JAR.

EDIT: Solved-ish the problem? So the JAR file needs to the in a folder with all the original files? I am so confused, what is a JAR file then?

like image 462
Pedro Avatar asked Sep 07 '25 01:09

Pedro


2 Answers

A more robust way to get a file whether you are running from Eclipse or a JAR is to do

MyClass.getResource("items.txt")

where MyClass is a class in the same package (folder) as the resource you need.

If Eclipse is not putting the file in your JAR you can go to

Run -> Run Configurations -> -> Classpath tab -> Advanced -> Add Folders

Then add the folder containing your file to the classpath. Alternatively, export the Ant script and create a custom build script.

like image 167
Garrett Hall Avatar answered Sep 08 '25 14:09

Garrett Hall


To the point, the FileReader can only read disk file system resources. But a JAR contains classpath resources only. You need to read it as a classpath resource. You need the ClassLoader for this.

Assuming that Foo is your class in the JAR which needs to read the resource and items.txt is put in the classpath root of the JAR, then you should read it as follows (note: leading slash needed!):

InputStream input = Foo.class.getResourceAsStream("/items.txt");
reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
// ...

Or if you want to be independent from the class or runtime context, then use the context class loader which operates relative to the classpath root (note: no leading slash needed!):

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("items.txt");
reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
// ...

(UTF-8 is of course the charset the file is encoded with, else you may see Mojibake)

like image 29
BalusC Avatar answered Sep 08 '25 14:09

BalusC