FileNotFoundException only when I try to access CSV file within .jar
I have a class, JCalculator.class within com.ppowell.applications that works beautifully within NetBeans by accessing 2 important CSV files found within com.ppowell.applications.data - again, in NetBeans, absolutely no problem whatsoever finding them, accessing them and handling the data.
I then jarred the whole thing up into a Jar file, GUI.jar.
I also have a .properties file that helps in identifying the location of the CSV file by providing the dynamic source path:
com.ppowell.applications.Globals.JCalculatorGlobals.SRC_PATH = C:\\Program Files\\Java\\jdk1.6.0\\classes
Again, all of this in NetBeans is fantastic, works like a charm.
However, the goal is to create a fully-portable JAR file you can install almost anywhere and whose values are fully handled by the .properties file.
So when I installed GUI.jar onto my home computer, placed the .properties files in the correct location to be accessible, and made sure GUI.jar and all dependent .jar files were within the CLASSPATH, the moment I did this:
java -cp Tools.jar;GUI.jar com.ppowell.applications.JCalculator
The line that reads the CSV file throws a FileNotFoundException:
java.io.FileNotFoundException: File C:\Program Files\Java\jdk1.6.0\classes\\com\
ppowell\applications\data\jcalculatorbuttonkeycodes.csv does not exist.
However, opening up GUI.jar the CSV file does indeed exist, but in C:\Program Files\Java\jdk1.6.0\classes\com\ppowell\applications\data\jcalculatorbuttonkeycodes.csv
[notice the slight path change?]
The only way I can get JCalculator.class to work is to blow apart the JAR file, which I absolutely do not want to do if I want this to be fully portable and manageable by anyone who doesn't know Java out there.
Bottom line is this: How can I make sure the .properties file and the code work together to fully function whether a .jar file or separate classes?
Phil
There are no 'files' in a jar file. You should use Class.getResource() or getResourceAsStream() method to access 'resources' in a jar file.
hiwaa at 2007-7-10 0:42:47 >

So in my case would i do this:
InputStream in = JCalculator.class.getResourceAsStream("com.ppowell.applications.data.jcalculatorkeycodes.csv");
?
I am not sure if the path info into getResourceAsStream() must include the entire exact path from within the jar file but I assume it would, as the CSV files are found within com.ppowell.applications.data while the app is within com.ppowell.applications - all within GUI.jar
Phil
> "com.ppowell.applications.data.jcalculatorkeycodes.csv""/com/ppowell/applications/data/jcalculatorkeycodes.csv"
hiwaa at 2007-7-10 0:42:48 >

> yeah that sounds right.
That leads now to my next question. How then would I be able to do a full-scale access when I have my applications in two states:
1) As standalone applications unjarred while in testing mode within NetBeans
2) As a .jar file
Obviously MyApp.class.getResourceAsStream("/path/to/file-that-is-not-a-file") won't work if 1) is true.
> > yeah that sounds right.
>
> That leads now to my next question. How then would I
> be able to do a full-scale access when I have my
> applications in two states:
>
> 1) As standalone applications unjarred while in
> testing mode within NetBeans
>
> 2) As a .jar file
>
> Obviously
> MyApp.class.getResourceAsStream("/path/to/file-that-is
> -not-a-file") won't work if 1) is true.
Yes it will! It searches for resources relative to the class path items so as long as the root is of "/path/to/file-that-is-not-a-file" is on the class path then the resource will be found.
> > > yeah that sounds right.
> >
> > That leads now to my next question. How then would
> I
> > be able to do a full-scale access when I have my
> > applications in two states:
> >
> > 1) As standalone applications unjarred while in
> > testing mode within NetBeans
> >
> > 2) As a .jar file
> >
> > Obviously
> >
> MyApp.class.getResourceAsStream("/path/to/file-that-is
>
> > -not-a-file") won't work if 1) is true.
>
> Yes it will! It searches for resources relative to
> the class path items so as long as the root is of
> "/path/to/file-that-is-not-a-file" is on the class
> path then the resource will be found.
I'm sorry let me explain again.
Consider this:
// using com.csvreader.CsvReader which takes String fileName
JCalculator.this.reader = new CsvReader(System.getProperty("com.ppowell.applications.Globals.JCalculatorGlobals.SRC_PATH") + FileFunctionality.buildFilePath(JCalculatorGlobals.DATA_PATH_ARRAY) +
File.separator +
this.outerClassName +
"buttonnamesvalues.csv");
It is dynamically building a file path all the way from the value imported into System.getProperty() from a variable within a .properties files, which right now assumes the file is there.
Aside from the dynamic properties of the file path, the mere fact that I am using CsvReader which does not take InputStream as a parameter (see http://cweiske.de/howto/javadoc-CSVReader/de/cweiske/tools/CSVReader.html ) means that getResourceAsStream() into an InputStream would be useless because I would have no way for CsvReader to read it.
Ideas?
You are not using a very good CSV reader if it won't allow input from a stream. Have you looked at opencsv from http://opencsv.sourceforge.net/ . This will allow the construction of a CSV reader from a Reader which of course can be constructed from an InputStream.
Also, the CSV Parser from http://ostermiller.org/utils/doc/ also allows input from an InputStream so you can take your choice..
> You are not using a very good CSV reader if it won't
> allow input from a stream. Have you looked at opencsv
> from http://opencsv.sourceforge.net/ . This will
> allow the construction of a CSV reader from a Reader
> which of course can be constructed from an
> InputStream.
>
> Also, the CSV Parser from
> http://ostermiller.org/utils/doc/ also allows input
> from an InputStream so you can take your choice..
I'll remember that going forward, however, way too much code would have to be changed now not just for CsvReader but XMLWriter, XMLReader, TextReader, HTMLReader, etc.
I am now trying to write a "function" that will render the files for me, but I'm running into a syntax snag here and I don't know how to solve it:
InputStream in =
myClass.getResourceAsStream(packagePath.replace(".", File.separator) +
File.separator +
fileName);
try {
OutputStream out = new FileOutputStream(filePath);
int data;
while ((data = in.read()) != null) {
out.write(data);
}
out.close();
in.close();
return FileFunctionality.isFile(filePath);
} catch (IOException e) {
e.printStackTrace();
return false;
}
I am getting "Incompatible types: int and <nulltype>" at
while ((data = in.read()) != null) {
out.write(data);
}
And if I change "null" to false, I get "Incompatible types: int and boolean", and it just keeps going.
What on earth do I write?
Phil
