FileNotFoundException while running as a jar - java

FileInputStream fstream = new FileInputStream("abc.txt")
is throwing a FileNotFoundExceptionn while running as a jar. Why ? Normally it is able to find while running from main method.

class MyClass{
InputStream fstream = this.getClass().getResourceAsStream("abc.txt");
}
This code should be used.
And the files(in this case abc.txt) should be kept , in the Object references class location. That means , this.getClass refers to the location of some folder i.e, com/myfolder/MyClass.java folder .
So we should keep the abc.txt in com/myfolder this location.

If your file is packaged with your jar then you should to get information using getClass().getResource(url):
FileInputStream inputStream =
new FileInputStream(new File(getClass().getResource(/path/to/your/file/abc.txt).toURI()));
Else you need to create it always in the same path with your jar and you can get it like you do :
src/myJar.jar
src/folder/abc.txt
FileInputStream fstream = new FileInputStream("folder/abc.txt");
You can read here also :
How do I load a file from resource folder? and File loading by getClass().getResource()

You can use FileInputStream only when you actually have a file on the computer's filesystem. When you package your text file in the jar file for your program, it is not a file in the filesystem. It is an entry inside the jar file.
The good news is that it is even easier, in Java, to access the file this way: it is in your classpath, so you can use getResourceAsStream().
InputStream stream = getClass().getResourceAsStream("abc.txt");
If you have your classpath set up correctly, this will work regardless of whether it is a file in a directory (such as during development), or an entry in a jar file (such as when released).

It's because your working directory will probably be different under the two environments. Try adding the line
System.out.println(new File("abc.txt").getAbsolutePath());
to see where it is actually looking for the file.

Related

Why won't input stream find a file outside of the class folder

I want to want to use input stream with a file "NewFile.java", the code I have works fine if the file is situated in the same folder as the .class file that is performing the action. But once I move I get null reference.
I have tried using absolute and relative paths with and without a '/' at the start.
InputStream in = getClass()
.getResourceAsStream("NewFile.java");
I would like to source the file when it is located in the root directory of the project.
Better use InputStream in= new FileInputStream(new File("path/to/yourfile"));
The way you are using it now is as a resource which has to be in the class path.
getResourceAsStream() is not meant to open arbitrary files in the filesystem, but opens resource files located in java packages. So the name "/com/foo/NewFile.java" would look for "NewFile.java" in the package "com.foo". You cannot open a resource file outside a package using this method.
There is a distinction between files on the file system, and resources, on the class path. In general a .java source file won't be copied/added to the class path.
For a class foo.bar.Baz and a resource foo/bar/images/test.png one can use
Baz.class.getResourceAsStream("images/test.png")
Baz.class.getResourceAsStream("/foo/bar/images/test.png")
As you see the paths are class paths, possibly inside .jar files.
Use file system paths:
Path path = Paths.get(".../src/main/java/foo/bar/Baz.java");
InputStream in = Files.newInputStream(path);
List<String> lines = Files.readAllLines(path);
List<String> lines = Files.readAllLines(path, StandardCharsets.ISO_8859_1);
Files.copy(path, ...);

Referencing file from within the same JAR file as the application

I have a Java application in Eclipse that references .XML files as templates for other functionality. Usually I package the .JAR file without these files, because placing them within the same folder as the .JAR file seems to work fine with this reference:
File myFile = new File("templates/templateA.xsd");
I now require that these templates be placed within the same .JAR file as this application. I can include them with no problems, but these references no longer seem to work.
Is there a correct way of referencing the .XML file from within the same .JAR that the application is running from?
You need to know how to load the files from class path.
one of the ways is as follows
class XMLLoader {
public String loadXML(String fileName){
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName);
// do the loading of the file from the given input stream.
}
}
you know that the "templates" folder should be inside of your jar.
If you just need to read this file, you might not need a java.io.File but just an InputStream that you can get via
this.getClass().getResourceAsStream("templates/templateA.xsd")
If you really need a java.io.File... I do not know... The last time a really needed a File, I just copied the InputStream to a temporary file but this is ugly.

Access file from another package

My situation is as following : I have package packA where I have classA, and I have a file.txt in packB.resources. In classA I'm using this to access file.txt :
InputStreamReader in = new InputStreamReader(new FileInputStream("/packB/resources/file.txt"), "UTF-8");
But unfortunately it shows me an exception :
java.io.FileNotFoundException : \packB\resources\file.txt (The
specified path was not found)
The FileInputStream class opens a file in the file system based on a file system path.
But what you are apparently trying to do is to open a resource located via the classpath. You should be using Class.getResourceAsStream(String).
If your file.txt is packaged with application you should not access using file system at all. The application may be packaged into jar, so the file is not located in file system. You should access it as a resource instead:
InputStreamReader in = new InputStreamReader(getClass().getResourceAsStream("/packB/resources/file.txt"), "UTF-8"));
Use something like the following. Note, the / used as a prefix before the package name. YourClass is assumed to be in packA.
InputStream stream = YourClass.class.getResourceAsStream("/packB/resources/file.txt");
You should remove the trailing / from the file path and use classA.class.getClassLoader().getResourceAsStream("packB/resources/file.txt").

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

Find where Java loads files from?

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("."));

Categories