2

I have a Swing Java program that reads *.txt files in a resource folder called 'res' containing subfolders of different kind of JSONs. When I run directly from Eclipse, all is fine. If I create an executable jar it doesn't work. I managed to make it work with an horrifying solution, putting all my text files in the package where they are called.

To read them I use this line of code:

InputStream is = this.getClass().getResourceAsStream(file + ".txt");

where file is a string. I thought this would search in the jar the specified file but obviously not. I tried to put the path to the files, res/subfolder/name_of_file.txt and subfolder/name_of_file.txt but to no avail. Here is the structure of my project

Project
   src
      com.package
   res
      JSON_type1
      JSON_type2
         file.txt

From com.package, I have a class that must read from JSON_type2/file.txt. Besides the obvious reason to keep my text file organized in the subfolders is that my GUI will populates a drop down list with the content of those subfolders.

From what I've gather from other questions here, getResourceAsStream() would have been my solution if I wanted to keep my text files in the package where they are called. Other than that I found something about subclassing ClassLoader and overwriting findResource(). If possible I want to avoid this solution as I'm far from being familiar with that class and its functionalities.

Should you need more informations, let me know.

Thank you

P.S.: This question arose from my previous question here

Community
  • 1
  • 1
Chamane
  • 77
  • 1
  • 1
  • 8

3 Answers3

4

You can address files in the packages by dividing them with slashes, for example for file.txt you should getResourceAsStream("/res/JSON_type2/file.txt")

The slashes are not for folder stucture and not platform dependant, they're just the way the classloader addresses files.

  • Can you clarify what you mean by "not for folder structure"? My text files are in folders with the path _res/JSON_type2/file.txt_. I added my folder _res_ to the build path (and the subfolders JSON_typeX got a decoration I've never seen before, sort of white package with what seems to be an open folder). So I don't know if adding my _res_ folder to the Build Path makes it a package, but from what I understand it's just a folder with subfolders with no code in it. Either way, putting the path like this throws me a custom exception saying that the InputStream is null. – Chamane Apr 23 '12 at 18:46
  • Oh sure, the package structure of jar files (or to be more generic java classpaths) is indeed arranged in folders, but the character you use to address them the "/" can be kind of confusing, specially if you're used to unix environments, but if you switch to windows environments you should not change the / for a \, because it is only a character that the classloader uses to separate packages on the classpath and not a real folder separator. – Juan Alberto López Cavallotti Apr 23 '12 at 18:59
4
// added leading / to indicate search from root of class-path
String file = "/res/JSON_type2/file.txt";
InputStream is = this.getClass().getResourceAsStream(file);
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Maybe my problem lies somewhere else then. Using this path gives my an error, but if I put the text files in src/com.package and use `this.getClass().getResourceAsStream("file.txt");` it works. Any idea where I might look for another error? – Chamane Apr 23 '12 at 18:52
  • Yup it still works. But I want to have my text file in the folder res/JSON_type2 and not in the package com.package – Chamane Apr 23 '12 at 19:26
  • It's a matter of figuring where the `file.txt` is located in a Jar file, and ensuring that Jar is on the run-time class-path of the app. This is one of the times it is handy to be able to list the Jar contents from the command line, or inspect it using a Zip or archive tool. – Andrew Thompson Apr 23 '12 at 20:06
  • 1
    Oh wow, that is kinda annoying. Exporting as a runnable jar remove 'res' from the path. That doesn't really matter. What is weird is that if I use "/JSON_type2/file.txt", all my unit test will fail, but the runnable jar works. Using "file.txt" or "com/package/file.txt" will work both in the runnable and Eclipse but that means having my text file in the package. So it's either to make it work everywhere with the wrong structure or have work only in the runnable with the structure I want. – Chamane Apr 23 '12 at 20:21
  • Glad you at least figured what was going wrong. Perhaps someone can suggest a way to sort the path for all 3 (JUnit/Eclipse/Runnable Jar) situations. As an aside, good question. – Andrew Thompson Apr 23 '12 at 20:30
1

I was able to get basically the functionality you are looking for in Eclipse by doing this:

src (folder)
   main (package)
      ...Classes...
other (folder)
   res  (package)
      ...txt files...

It seems that Eclipse completely ignores folders and only cares about packages. As long as I put my text files in a package, I am able to grab an InputStream with getResourceAsStream("/res/somefile.txt").

Jonathon
  • 11
  • 1