Reputation: 1507
I am having trouble accessing a file within my Jar on Windows. I do not have this problem when I run it on Unix. I have created the jar both on Windows & Unix and it makes no difference. Either way it does not run on Windows.
I ran the jar -tf command on my jar and the class I am running from is located in: a/b/c/d/ClassOne.class. The class I am looking for is located in my base directory of the jar: ClassTwo.class
My code in this ClassOne looks like the following:
String path = File.separator + "myYAML.yml";
InputStream in = MetricCollector.class.getResourceAsStream(path);
InputStreamReader isr = new InputStreamReader(in);
BufferedReader input = new BufferedReader(isr);
My code breaks on the last line shown throwing a NullPointerException which I can only believe means it cannot find the path I have given it. However, this exact code works great on my debugger and on Unix when I run the jar.
I have also tested the following paths:
"myYAML.yml"
File.seperator + ".." + File.seperator + ".." + File.seperator + ".." + File.seperator + ".." + "myYAML.yml"
".." + File.seperator + ".." + File.seperator + ".." + File.seperator + ".." + "myYAML.yml"
all to no avail.
I have used the following Stack Overflow posts to get as far as I can, but they do not seem to have an answer for me: How to reference a resource file correctly for JAR and Debugging?, Accessing resources within a JAR file and Reading file from within JAR not working on windows
Any additional help I would be extremely grateful for. Thanks in advance.
Upvotes: 0
Views: 207
Reputation: 279910
File.separator
cannot work on Windows, it returns \
. You need to use /
as a separator regardless of the OS.
The Class#getResource(String)
states
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'. Otherwise, the absolute name is of the following form: modified_package_name/name
Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').
In other words, you must use /
. This is further explained in the javadoc for ClassLoader.html#getResource(java.lang.String)
to which Class#getResource
delegates.
The name of a resource is a /-separated path name that identifies the resource.
If the resource is at the root of the classpath, use
InputStream in = MetricCollector.class.getResourceAsStream("/myYAML.yml");
Upvotes: 3