Find where Java loads files from? - java

I was just wondering if there is a way to find out where a java program will be searching for files.
I am trying to load a settings file with FileInputStream fstream = new FileInputStream("ldaplookup.ini"); but it is throwing a File not found error. The ini file is in the same folder as the class file but i am assuming it is searching somewhere else.
Thanks, -Pete

FileInputStream looks up the file relative to the path of execution. If the resource file is in the same folder as the class, you can try using:
InputStream stream = this.getClass().getResourceAsStream("ldaplookup.ini");

Java loads files from the current working directory for a relative path. If you want to see what is, try this:
System.out.println(System.getProperty("user.dir"));

Since "new FileInputStream("ldaplookup.ini");" is equivalent to "new FileInputStream("./ldaplookup.ini");", you could try:
System.out.println(new File(".").getAbsolutePath());

A much more reliable method to read files that are distributed with your classes is to use Class.getResourceAsStream() - it will look in the directory in the classpath where the class you're calling it on is situated, and it will even work when everything is packaged in a JAR file.

Not direct answer but a helpful alternative:
You can use a resource bundle instead.
rename ldaplookup.ini to ldaploopup.properties
And load it with:
ResourceBundle bundle = ResourceBundle.getBundle("ldaplookup");
String s = bundle.getString("url");
ResourceBundle search in the classpath for a .properties file among other strategies.
Etc. etc.
p.s.
To know what is the base path for your program try ( as suggested before: )
System.out.println(new File("."));

Related

Jar is not loading resources file

I have a project with a folder "src/main/resources" where inside there is the hibernate configuration file, I load it using this line of code
HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()
From inside the IDE it is working well, but when I create the jar it doesn't file the file.
How can I load it properly in the jar file too?
Thanks
Could you please try this:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileName").getFile());
I cannot say for ceratin that this is the issue without knowing how exactly you use the path extracted by:
HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()
but I can tell you this:
Run from an IDE the above line of code will return:
/path/to/project/src/main/resources/hibernate.cgf.xml
which is a valid filesystem path. You can then use this path to, for example, create an instance of File class and then use that instance to read the file contents.
However the same line of code run from inside a jar file will return:
file:/path/to/jar/jar_name.jar!/hibernate.cgf.xml
which is not a valid filesystem path. If you create an instance of File class using this path and then try to read the contents of the file you'll get an exception: java.io.FileNotFoundExeption
To read the contents of the file from inside of a jar you should use method Class.getResourceAsStream(String), which will return an instance of class sun.net.www.protocol.jar.JarURLConnection.JarURLInputStream (or equivalent in non-Oracle or non-OpenJDK Java). You can then use this object to read the contents of the file. For example:
InputStream inputStream = HibernateUtil.class.getResourceAsStream("/hibernate.cgf.xml");
Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
String fileContents = scanner.hasNext() ? sscanner.next() : "";
Most likely, the file is absent from the jar you create. There's too little information in your question, but I will try a guess:
Your hibernate.cgf.xml resides in the same directory as the Java sourcefles, and you are using a build tool (be it IDE, maven, gradle or an ant script) that expects resources to be stored in a separate directory.
It's easy to check: try to unzip your jar and see if the file is there (use any tool, you can just change the extension from .jar to .zip). I think you will see the file is absent.
Then come back with a question: "how to pack my non-java resources into a jar, using XXX", where XXX will be the name of the techology you are using for building the jar.
Most probably the slash in "/hibernate.cgf.xml" is not needed, if the hibernate.cgf.xml is in the same package as you class HibernateUtil.
You can access the file actually also via the classloader using the full path. Yet you never add to it the first slash.
Here is some code demonstrating how you can access the file using different methods:
public static void main(String[] args) {
// Accessing via class
System.out.println(SimpleTests.class.getResource("hibernate.cgf.xml").getPath());
// Accessing via classloader from the current thread
String path = Thread.currentThread().getContextClassLoader()
.getResource("simple/hibernate.cgf.xml").getPath();
System.out.println(path);
// Accessing via classloader used by the current class
System.out.println(SimpleTests.class.getClassLoader().getResource("simple/hibernate.cgf.xml").getPath());
}
In the example above the package 'simple' should be replaced by the package where your hibernate.cgf.xml is. But you should never have the slash at the beginning of the package declaration.

How do I get the File API to look at my classpath?

I am reading an ascii file in in my eclipse project.
The default output folder is set as
my_proj/classes
It is on my source path and when I build it goes into my classes directory. All ok. However, when I try to get a handle to it in my code by doing
File myFile = new File("myFile.txt")
it won't work because that API looks at my project root. Not at my classes dir.
When I do:
System.out.println("Current path is = " + new File(".").getAbsolutePath ());
The project roo comes back not my classes dir.
So hence I can't get a handle to my File.
I would like to just have the File on the classpath and for the code to pick it up
Any tips?
You can use getClass().getClassLoader().getResource("Your_File")
and then use something like
File file=new File(url.toURI());
Edit: as pointed out by Sotirios Delimanolis and jb-nizet, if "Your_File" is not a file on the file system but is bundled within a jar, in that case you will have to work with the inputstream, getClass().getClassLoader().getResourceAsStream("Your_File")

Eclipse-Java: where to put file for Read purpose

I'm programming Java in Eclipse IDE. Here is code I want to read file:
File file = new File("file.txt");
reader = new BufferedReader(new FileReader(file));
I put file.txt in two place:
1) same folder of this SOURCE file.
2) in bin\...\ (same folder of this CLASS file)
But I allways receive NO FILE FOUND.
Please help me.
thanks :)
If the file ships with your application, it would be better accessed as a resource than as a file. Simply copy it to somewhere in your build path and use Class.getResourceAsStream or ClassLoader.getResourceAsStream. That way you'll also be able to access it if you bundle your app as a jar file.
Currently, you're looking for the file relative to the process's current working directory, which could be entirely unrelated to where the class files are.
if you put the file under sources and inside the package "test" for example, the path is:
./src/test/file.txt
you can use
File file = new File("./src/test/file.txt");
System.out.println(file.exists());
The path ./bin/test/file.txt will work in the second case and is more suitable for a normal java project

Java FileNotFoundException when running a jar file

In my project I load my resource using
getClass().getResource("/package/my_reource.file").getFile()
All works good when I run the project in netbeans, but if I run the jar file, I get FileNotFoundException, why?
Thanks.
You can use InputStream rather than getClass().getResource("/package/my_reource.file").getFile()
You should use
getClass.getResourceAsStream("/package/myresource.file")
I don't think you need the filename. You rather need its content. So use getResourceAsStream() to obtain the InputStream and read the content from there.
Check your jar. I believe that your file is not there.
The reasons depend on how are you creating your jar. If you are doing it using netbeans, check your settings. Probably it includes only *.class files? The same is about ant. Check tag.
The getFile() returns the file path portion of the URL returned by getResource()
So if its in the Jar, you have to read the jar to gett he file. If its on the filesystem you can read using FileInputStream.
If you want to get the InputStream and you don't create where you get it from use getResourceAsStream()

Open file; try filesystem first, then JARs

I'm trying to have my application load a resource (binary file) transparently:
If the file exists under the current directory, open it.
If not, try looking in the current JAR file if applicable.
If not, try looking in other JAR files. (This is optional and I don't mind explicitly specifying which JAR files.)
So far I know of File which opens a local file and ClassLoader which has getResource* for JAR contents.
Is there a class which combines the two? If not, how should I go about writing it myself? Should I write a ClassLoader which also checks the local filesystem? Using File? (I'm very unfamiliar with Java and don't even know what's a good type to return. InputStream?)
Thanks
P.S. By "file" I mean "path", e.g. "data/texture1.png".
Doing #1 and #3 is pretty easy. Doing #2 (just looking in the current JAR only) is much harder as it requires you figuring out what JAR you
If you wanted to check the filesystem first, otherwise load from classpath, it would be something like:
public java.io.InputStream loadByName(String name) {
java.io.File f = new java.io.File(name);
if (f.isFile()) {
return new FileInputStream(f);
} else {
return getClass().getResource(name);
}
}
If you want to prefer loading from the same JAR file first, you will need to figure out where it is. Check out Determine which JAR file a class is from for more info on figuring out the JAR file you want to load the resource from.
A URLClassLoader should be able to load both and try the file path first if the file path is on the class path ahead of the jar.
Regarding your comments:
I know that relative jar URLs don't
work. That's why the Spring guys came
up with the Resource abstraction.
Read about it here.
You might want to check the answers
to this Question: Loading a file
relative to the executing jar
file. The problem is similar to
yours.
Current jar file and current directory are not concepts in the JVM like they are when you're running a shell script. You would need to specify a directory to be used for loading the files that you're interested in, such as with a system property while executing the JVM:
java -Ddirectory.to.scan=/home/aib
Then retrieve this property:
String dir = System.getProperty("directory.to.scan");
Now when talking about JAR files, all JAR files specified explicitly on the classpath when you start the JVM are loaded by the ClassLoader. You can get the ClassLoader of a specific class by:
InputStream is = <Your class>.class.getClassLoader().getResourceAsStream("binary file");
Note that any jar file loaded by the current class loader is searched.

Categories