Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / February 2006

Tip: Looking for answers? Try searching our database.

Crazy jar resource access problem

Thread view: 
JavaEnquirer - 22 Feb 2006 18:32 GMT
An application gets launched - application.jar. The application calls a
method on a second jar - utility.jar. This method's job is to load a
resource from application.jar. How do you achieve this? When
utility.jar attempts to  access a jar resource, the usual method of
using a class loader doesn't work, as its class loader is for itself,
not application.jar!

How do you get around this? I've tried a few things e.g.

1. adding application.jar to utility.jar's class path ( horrid coupling
),

2. passing a reference to application.jar's class loader to utility.jar
to use to access application.jar's resources.

Neither works!! Any ideas? This is really frustrating and I can't
believe that no one else has this problem. Surely, when developing
desktop applications, it's common practice to farm out resource
management code to an external, reusable jar, and then expect it to
access resources in the main application jar. Aargh! Many thanks in
advance.
JavaEnquirer - 22 Feb 2006 19:12 GMT
Ah, just one other thing. I've posted this problem a couple of times
and a number of people have kindly replied. However, I  haven't done a
good job of explaining the problem. I'm not simply trying to load an
image from within the same jar as the code interested in the image.
That's straight forward. Neither am I trying to get the main
application jar to load an image from a secondary jar referenced by the
main jar's classpath.

I'm trying to get the utility jar to access a resource in the main jar
- the reverse of what's normally going on! And, as its a utility jar,
to be reused, it shouldn't reference the main application jar on its
classpath.

I'd have thought this was a classic - resource loading code in a
utility jar able to load resources from any arbitrarily specified jar
at runtime.
Chris Uppal - 23 Feb 2006 11:41 GMT
> I'm trying to get the utility jar to access a resource in the main jar
> - the reverse of what's normally going on! And, as its a utility jar,
[quoted text clipped - 4 lines]
> utility jar able to load resources from any arbitrarily specified jar
> at runtime.

I think you'll have to pass a "token" from the main application to the utility
library to say /where/ to look for the resource.  The utility library should
not "know" about the main application's JAR (or anything else about it).  The
obvious "tokens" to pass are either the classloader of the main application or
one or more of the java.lang.Class objects from the app.

You then have the choice of building some sort of registry in the utility
library which the application populates with tokens as part of its
initialisation (or later, I suppose), or of designing the API so that you
always pass a token as a parameter to any call to a resource-loading utility
method.  (Or a hybrid of the two.)

Or maybe you've already tried that and it didn't work ?  (I didn't follow your
earlier thread.)

   -- chris
JavaEnquirer - 23 Feb 2006 13:01 GMT
> I think you'll have to pass a "token" from the main application to the utility
> library to say /where/ to look for the resource.  The utility library should
[quoted text clipped - 10 lines]
> Or maybe you've already tried that and it didn't work ?  (I didn't follow your
> earlier thread.)

Cheers. Yep I tried this but to no avail!
Chris Uppal - 23 Feb 2006 14:18 GMT
> > Or maybe you've already tried that and it didn't work ?  (I didn't
> > follow your earlier thread.)
>
> Cheers. Yep I tried this but to no avail!

What's the problem ?   It works for me (details follow below).  What are you
doing, or needing to do, differently ?

   -- chris

===== App.java =======
package application;

import utilities.Utils;

public class App
{
public static void
main(String[] args)
{
 new App().doit();
}

private void
doit()
{
 Class<?> c = this.getClass();

 System.out.println("Res1: " + c.getResource("res1.txt"));
 System.out.println("Res2: " + Utils.findResourceFor(c, "res2.txt"));
}
}
============

====== Utils.java ======
package utilities;

public class Utils
{
public static java.net.URL
findResourceFor(Class<?> c, String name)
{
 return c.getResource(name);
}
}
============

Compile and build JARs, then:

$ jar -tf A.jar
META-INF/
META-INF/MANIFEST.MF
application/
application/App.class
application/res1.txt
application/res2.txt

$ jar -tf U.jar
META-INF/
META-INF/MANIFEST.MF
utilities/
utilities/Utils.class

$ java -cp "U.jar;A.jar" application.App
Res1: jar:file:/C:/Home/tmp/app-res/A.jar!/application/res1.txt
Res2: jar:file:/C:/Home/tmp/app-res/A.jar!/application/res2.txt
JavaEnquirer - 23 Feb 2006 16:51 GMT
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.

> > > Or maybe you've already tried that and it didn't work ?  (I didn't
> > > follow your earlier thread.)
[quoted text clipped - 62 lines]
> Res1: jar:file:/C:/Home/tmp/app-res/A.jar!/application/res1.txt
> Res2: jar:file:/C:/Home/tmp/app-res/A.jar!/application/res2.txt
Chris Uppal - 23 Feb 2006 17:42 GMT
> 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.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.