Access Data Inside JAR

J

Jason Cavett

If this is not the place to ask, I'd appreciate it if you could direct
me to the correct place.

I am creating an executable JAR from a project that has the following
structure (I'm developing in Eclipse):

Project
- src files
- resources
- icons
- config

Inside the config directory is a default config file. If the user
does not have a personalized config file, I want the default one to be
read into an object and then, when the user is finished, that object
will be written to their home directory so they have a personalized
config file in the future.

The problem is, I can't seem to access the config file. I can access
the icons in the icons folder, but I'm stuck on how to get to the
config file. (I tried ClassLoader.getSystemResource("resources/config/
config.xml") but that always throws a NullPointerException.)

If anybody could point me in the right direction, I'd appreciate it.


Thanks
 
A

Andrew Thompson

The problem is, I can't seem to access the config file. I can access
the icons in the icons folder, but I'm stuck on how to get to the
config file. (I tried ClassLoader.getSystemResource("resources/config/
config.xml") but that always throws a NullPointerException.)

Really? AFAIU, getSystemResource() might return
a null URL, but it does not actually throw NPE's
itself.

OTOH, I would usually *not* use the system class
loader for my own application's resources.
Instead, I recommend you try plain old
'getResource()'.

Once done, print the URL. If it is 'null',
it might be that this call has been done too
early in the process, using the 'root'
(or whatever Sun calls it) class loader that
is really only good for classes.

Sometimes this can happen if you call it in
the program's main(), for example. It is
usually better to attempt it from within
(for example) a constructor for the class.

HTH

Andrew T.
 
P

Philipp

Jason said:
If this is not the place to ask, I'd appreciate it if you could direct
me to the correct place.

I am creating an executable JAR from a project that has the following
structure (I'm developing in Eclipse):

Project
- src files
- resources
- icons
- config

Inside the config directory is a default config file. If the user
does not have a personalized config file, I want the default one to be
read into an object and then, when the user is finished, that object
will be written to their home directory so they have a personalized
config file in the future.

The problem is, I can't seem to access the config file. I can access
the icons in the icons folder, but I'm stuck on how to get to the
config file. (I tried ClassLoader.getSystemResource("resources/config/
config.xml") but that always throws a NullPointerException.)

If anybody could point me in the right direction, I'd appreciate it.

Probably you want to read the data out of this config file, so you
should use getResourceAsStream(String name) which will return an
InputStream.

HTH
Phil
 
P

Philipp

Philipp said:
Probably you want to read the data out of this config file, so you
should use getResourceAsStream(String name) which will return an
InputStream.

OTOH you might be interested in the fact that there is a Preferences
class (java.util.prefs.Preferences) which can handle the config stuff of
your app in a nice and platform independent way (also providing defaults
when a value is not found).

Phil
 
J

Jason Cavett

OTOH you might be interested in the fact that there is a Preferences
class (java.util.prefs.Preferences) which can handle the config stuff of
your app in a nice and platform independent way (also providing defaults
when a value is not found).

Phil- Hide quoted text -

- Show quoted text -

Thanks for your help Phillip and Andrew. But, the resource is still
coming back as "null" no matter what I try to do. Here's the portion
of my code in question...

URL mainURL = this.getClass().getResource("resources/config/
config.xml");
(I also tried - URL mainURL = this.getClass().getResource("/resources/
config/config.xml"); )

This always returns null. However, this works (if the file isn't
packaged in a JAR):

File mainFile = new File("resources/config/config.xml");


Any other suggestions? All this config file is is a default file that
is used if the user does not have their own personalized config file,
so I don't need to write to this config file - only read it.
 
P

Philipp

Jason said:
Thanks for your help Phillip and Andrew. But, the resource is still
coming back as "null" no matter what I try to do. Here's the portion
of my code in question...

URL mainURL = this.getClass().getResource("resources/config/
config.xml");
(I also tried - URL mainURL = this.getClass().getResource("/resources/
config/config.xml"); )

This always returns null. However, this works (if the file isn't
packaged in a JAR):

File mainFile = new File("resources/config/config.xml");


Any other suggestions? All this config file is is a default file that
is used if the user does not have their own personalized config file,
so I don't need to write to this config file - only read it.

That's why I told you to use getResourceAsStream(). AFAIK you can't open
the URL you get back from getResource() as a File (don't ask me why).

If you actually want to read something from it use getResourceAsStream()

Maybe you also want to use:
getClass().getClassLoader().getResourceAsStream("resources/config/config.xml");

or in a static method:
Thread.currentThread().getContextClassLoader().getResourceAsStream("resources/config/config.xml")

Phil
 
J

Jason Cavett

That's why I told you to use getResourceAsStream(). AFAIK you can't open
the URL you get back from getResource() as a File (don't ask me why).

If you actually want to read something from it use getResourceAsStream()

Maybe you also want to use:
getClass().getClassLoader().getResourceAsStream("resources/config/config.xm­l");

or in a static method:
Thread.currentThread().getContextClassLoader().getResourceAsStream("resourc­es/config/config.xml")

Phil- Hide quoted text -

- Show quoted text -

The problem isn't in reading what I'm getting back...it's the fact
that I'm not getting anything back at all...

InputStream stream = getClass().getClassLoader().getResourceAsStrea("/
resources/config/config.xm­l");
System.out.println(stream);

Output...

null

It's extremely annoying because I can get the images (which are in
resources/images) just fine.
 
J

Jason Cavett

The problem isn't in reading what I'm getting back...it's the fact
that I'm not getting anything back at all...

InputStream stream = getClass().getClassLoader().getResourceAsStrea("/
resources/config/config.xm­l");
System.out.println(stream);

Output...

null

It's extremely annoying because I can get the images (which are in
resources/images) just fine.- Hide quoted text -

- Show quoted text -

Well...now I'm confused...

When I run the code as an executable JAR, it works the way you said it
should (using an InputStream from the getResourceAsStream(String)).
But, when I run the code from Eclipse, the direct file method works.
Each method does not work with the other way of running the
application (and results in a FileNotFoundException or
NullPointException).

I prefer the JAR method, but, I still want to be able to run my code
via Eclipse since it's great for debugging, etc.

Any suggestions on this?
 
C

Chris Uppal

Jason said:
URL mainURL = this.getClass().getResource("resources/config/
config.xml");

That will be looking for the config.xml in a place relative the class's
location in the jar. E.g. if "this" is an instance of my.stuff.MyClass, then
the above will be looking for:
my/stuff/resource/config/config.xml

If that isn't what you want then you should adjust accordingly. It may help to
know that when you ask the class's classloader for the resource (instead of
asking the class itself directly) the path you provide is taken relative to the
root of the containing JAR file (or directory tree).

-- chris
 
J

Jason Cavett

That will be looking for the config.xml in a place relative the class's
location in the jar. E.g. if "this" is an instance of my.stuff.MyClass, then
the above will be looking for:
my/stuff/resource/config/config.xml

If that isn't what you want then you should adjust accordingly. It may help to
know that when you ask the class's classloader for the resource (instead of
asking the class itself directly) the path you provide is taken relative to the
root of the containing JAR file (or directory tree).

-- chris

Okay, well, that makes sense (and works when I try it). But why
doesn't this work within Eclipse? If I use the System classloader, it
works fine in the executable JAR but does not work when I run it
within Eclipse? (I know this is more of an Eclipse question - but it
is annoying that I can't do the same thing in one method of running
that I can do in another method.)

Thanks for your help.
 
P

Philipp

Jason said:
Okay, well, that makes sense (and works when I try it). But why
doesn't this work within Eclipse? If I use the System classloader, it
works fine in the executable JAR but does not work when I run it
within Eclipse? (I know this is more of an Eclipse question - but it
is annoying that I can't do the same thing in one method of running
that I can do in another method.)

It should. It works here, both ways (eclipse & jar).
Phil
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top