views:

266

answers:

1

I have a jar file with bundled resources (language model binary files) that need loading at run time. The directory structure within the jar is

tagger/app.class
tagger/models/stop/SentDetect.bin.gz

where SentDetect.bin.gz is a binary whos path is loaded into a thirdparty class (SentDetector) as a String parameter, i.e.

URL url = this.getClass().getResource("models/stop/SentDetect.bin.gz");
SentenceDetector sdetector = new SentenceDetector(url.getPath());

While it runs ok in Netbeans, when I try to run it as a jar from command line, I get a FileNotFound Exception at the constructor. I have double checked that the binary is included in the compiled Jar file.

I believe the solution would usually be to load the data in as an input stream using getResourceAsStream(), but this is not an option here, as the url is being passed as a String parameter to a third party constructor, which leads me to believe the problem is with how the url is being parsed to a String?

I have tried:

url.getPath();
url.getFile();
url.toURI().getPath();
url.toString();

and all are giving different paths to the file.

+1  A: 

It sounds like that should be fine, if the binary is definitely in the right place and the jar file is definitely in the class path. (I assume it can find the class itself? I'd expect so, given that you're using this.getClass()).

One thing which might be causing issues is filename casing - when it's loading the file from the file system, if you're using Windows that'll be case insensitive; in a jar file it'll be case sensitive. Check the case in code matches the case in the jar file.

Jon Skeet
You mean I can access a resource which is inside a jar using an URL from the outside of the application that has loaded the jar?
tangens
yea everything seems to be where it should, as I have no problems running the application from Netbeans, it only gives errors when I package it and run the jar on command line.
pastylegs
@tangens: If it's another Java app, quite possibly. Within the same Java app, but a different jar file - very likely. Within a normal web browser? Much less likely.
Jon Skeet
I thought you said the URL was null? If it isn't, that indicates a different root cause.
Jon Skeet
sorry that was a mistake, I will edit the original. The URL is not null, it is a valid path. When I print out the URL I get an absolute path such as: /a/b/c/nameofjar.jar!/tagger/models/stop/SentDetect.bin.gz which again is correct as far as I can see.
pastylegs
@pastylegs: What is SentenceDetector doing? Is it assuming that it's a URL for a regular file?
Jon Skeet
My solution has been to copy the models from within the jar to temporary files using createTempFile and load them from there. This seems to do the trick but unfortunately isn't the elegant solution I was looking for. I can only imagine that the problem lies with how the path to the models within the JAR is generated. Once I get a little more time I may come back and look into it further. Thanks for all the help
pastylegs