Thank you very much for your time and effort, its much appreciated.
However, the code you've suggested still doesn't work with my
particular configuration and needs. The only differences between what
I've been doing and what you suggest is, that I don't store my
resources relative to the class, instead I store them in a jar top
level folder called images.
Therefore, c.getResource isn't appropriate ( as far as I'm aware ), but
c.getClassLoader().getResource() is. However, as soon as this code goes
inside a jar it fails to work. I'm at a loss. Once again thanks for
your help. Maybe I'll try and post a simplified version of my code
complete with jar details as you have done.
> Thank you very much for your time and effort, its much appreciated.
You're welcome, it's something I wanted to get straight in my own mind, and
once I'd done that then why not post the code too ?
> However, the code you've suggested still doesn't work with my
> particular configuration and needs. The only differences between what
> I've been doing and what you suggest is, that I don't store my
> resources relative to the class, instead I store them in a jar top
> level folder called images.
That still works for me. Change my code to load:
System.out.println("Res1: " + c.getResource("/resources/res1.txt"));
System.out.println("Res2: " + Utils.findResourceFor(c,
"/resources/res2.txt"));
and change the A.jar so that:
$ jar tf A.jar
META-INF/
META-INF/MANIFEST.MF
application/
application/App.class
resources/
resources/res1.txt
resources/res2.txt
and then running it gives:
$ java -cp "U.jar;A.jar" application.App
Res1: jar:file:/C:/Home/tmp/app-res/A.jar!/resources/res1.txt
Res2: jar:file:/C:/Home/tmp/app-res/A.jar!/resources/res2.txt
Maybe the problem is to do with case-sensitivity, or you are using '\\'
separators instead of '/' somewhere (either in your code or in the JAR file
itself).
Another possibility is that you are getting confused by the (undoubtedly
confusing) difference between java.lang.Class.getResource() and
ClassLoader.getResource(). For a class object, the absolute (i.e. relative to
the archive's root rather than to the classfile itself) path must start with
'/' -- which makes sense. OTOH, ClassLoader.getResource() expects a name NOT
to start with '/' -- which also makes sense because a leading '/' would mean
the root of the filesystem for classloaders looking at directories rather than
JARfiles (and also because names in JAR/ZIP files must not have a leading '/').
-- chris
JavaEnquirer - 27 Feb 2006 10:30 GMT
Apologies everyone, I've been a bit on an idiot here. I was using a
File.separator buried deep in my code instead of a /, which is of
course the internal separator used by the zip/jar format. I was caught
out by unthinkingly and mistakenly going for what I thought was an file
system independent approach, when the problem was to do with an
individual file format. I spent my time worrying about class loaders
when the gotcha was a beginner's error.