Get the containing JAR's root

J

Joscha Diehl

Hi,
I found out how to get ressources in the JAR a class is in, if I know
its name (e.g. ...getResource("sample.gif") ).
What I want is to walk through the whole file to iterate over its
content. For that I have to get to the JAR's root. getReource("/")
won't work, neither does getRecource("").

Any ideas?`

Thanks

josh
 
A

Andrew Thompson

I found out how to get ressources in the JAR a class is in, if I know
its name (e.g. ...getResource("sample.gif") ).
What I want is to walk through the whole file to iterate over its
content. For that I have to get to the JAR's root.

Have you looked at the URL's Joscha??

String s = myURLToSubResource.toString();
return s.substring(0,s.lastIndexOf("!"));

HTH
 
J

Joscha Diehl

Andrew Thompson said:
Have you looked at the URL's Joscha??

String s = myURLToSubResource.toString();
return s.substring(0,s.lastIndexOf("!"));

you mean to use it and try getting it by an absolute url like this?:
jar:file:/C:/LocalData/JarAccess.jar

that won't work, at least getClass().getResource() returns null for that.

josh
 
A

Andrew Thompson

you mean to use it and try getting it by an absolute url like this?:
jar:file:/C:/LocalData/JarAccess.jar

No, I did not..

notice the term.. _Sub_Resource in the first line.

If you _get_ this back

jar:file:/C:/LocalData/JarAccess.jar!/files/icon.gif

...you just need the first part to know
what the jar file itself is. You can then
make a connection to it to get the enumeration.
[ etcetera ]
 
A

Andrew Thompson

(slaps forehead)

Sorry Joscha! I completely
misunderstood you. My bad.

So you _know_ the name of the zip file,
you already have the path, you just need
to know how to get the (dang) enumeration
of ZipEntries, right?

It sounds like you might need to
construct the URL yourself..
(new URL(getDocBase(), "MyJar.jar!"))
then use a
InputStream is = java.net.JarURLConnection().getInputStream()
to get the 'is' for a..
new java.util.zip.ZipInputStream(is)..
which can _finally_ do a getNextEntry()
and iterate though the elements.

Is there any easier and more direct way?
 
R

Roedy Green

you mean to use it and try getting it by an absolute url like this?:
jar:file:/C:/LocalData/JarAccess.jar

URL url = this.getClass() .getResource( "images/blueball.gif" );

// Depending on where getResource found the resource,
// the URL will look like one of the following:

// in local jar:
//
jar:file:/E:/com/mindprod/thepackage/thepackage.jar!/com/mindprod/thepackage/images/blueball.gif

// in remote jar:
//
jar:http://mindprod.com/thepackage.jar!/com/mindprod/thepackage/images/blueball.gif

// in local file:
// file:/E:/com/mindprod/thepackage/images/blueball.gif

// in remote file:
// http://mindprod.com/com/mindprod/thepackage/images/blueball.gif

If you know where the resource is, you could in theory get it directly
via its URL.
 
J

Joscha Diehl

hi again,

the problem is that I will *not* know the name of the jar file. And I
will *not* know the name of any ressource in that jar-File. So
getClass().getResource('whatever/blue.gif').toString().substring(0,name.indexOf('!')
will not work, because I don't have no 'blue.gif'.

I could use getClass().getName() + ".class", but it's not said that it
isn't already on the classpath somewhere else (I also tried
'META-INF/MANIFEST.NF' but he found it in rt.jar).

So .. even if that would work, it would be an ugly hack.
There must be some simple way to access the jar a class is from.

josh
 
M

Michael Rauscher

Hi Joscha,

Joscha said:
hi again,

the problem is that I will *not* know the name of the jar file. And I
will *not* know the name of any ressource in that jar-File. So
getClass().getResource('whatever/blue.gif').toString().substring(0,name.indexOf('!')
will not work, because I don't have no 'blue.gif'.

I could use getClass().getName() + ".class", but it's not said that it
isn't already on the classpath somewhere else (I also tried
'META-INF/MANIFEST.NF' but he found it in rt.jar).

So .. even if that would work, it would be an ugly hack.
There must be some simple way to access the jar a class is from.

josh

Perhaps

((URLClassLoader)getClass().getClassLoader()).getURLs()

helps you.

Bye
Michael
 
A

Andrew Thompson

I could use getClass().getName() + ".class", but it's not said that it
isn't already on the classpath somewhere else

What do you mean? You can use
the fully qualified class name..
 
J

Joscha Diehl

Michael Rauscher said:
((URLClassLoader)getClass().getClassLoader()).getURLs()

yeah, that works. but why is it []? can i relay on the the first entry
alway being the jar the class is from?

Also, it doesn't seem to work in J2EE. But that's no surprise because
there you got many classloaders. Have to investigate this further.

josh
 
T

Thomas Weidenfeller

Joscha said:
hi again,

the problem is that I will *not* know the name of the jar file. And I
will *not* know the name of any ressource in that jar-File.

So you know nothing.
So
getClass().getResource('whatever/blue.gif').toString().substring(0,name.indexOf('!')
will not work, because I don't have no 'blue.gif'.

So you have no means to find out something.

You have no file name, but you want to iterate over the contents of a
file. It must be that specific file, for which you haven't specified why
it is special, and how that particular file is different from all the
other jar files in your class path. All you have said is that there is a
jar which magically ended up in your class path, and you want to iterate
over its contents. Because, aehm, because you want it that way.

Most obvious conclusion: You have zero information to work with,
therefor you need a miracle or a crystal ball.

I strongly suggest you rethink your problem and you consider not to use
the class path for what you want to achieve (whatever it is that you
want to achieve, you haven't bothered to tell us).

If you want to mess with the class path (what is it that makes the class
path so attractive to mess with?), at least try to stack the cards in
your favor. E.g. place some marker file in the jar, like
"THIS-IS-MY-VERY-IMPORTANT-JAR". And use getResource() as it has been
explained to you several times to find the URL of that marker file.

Or use a fixed, well defined file name. Then pray that your system class
loader is a subclass of URLClassLoader. Get the system class loader, try
to cast it to a URLClassLoader. If successful, use getURLs() to get the
search path of the class loader. Examine each URL in that array if it
ends in your file name.

/Thomas
 
M

Michael Rauscher

Hi Josh,

Joscha said:
Michael Rauscher said:
((URLClassLoader)getClass().getClassLoader()).getURLs()


yeah, that works. but why is it []? can i relay on the the first entry
alway being the jar the class is from?

No. You can't rely on that. A ClassLoader can load classes from many
sources.

E.g. have a look at

java -cp .;first.jar;second.jar Main

If you call the above statement within Main, you should get three URLs.
(referring ".", "first.jar" and "second.jar" - as URL of course).
Also, it doesn't seem to work in J2EE. But that's no surprise because
there you got many classloaders. Have to investigate this further.

Do that.

Bye
Michael
 
J

Joscha Diehl

Thomas Weidenfeller said:
I strongly suggest you rethink your problem and you consider not to use
the class path for what you want to achieve (whatever it is that you
want to achieve, you haven't bothered to tell us).

well, the goal is to get an overview of all the class/package-tree in
the JAR-file.
I know that I could e.g. create an XML-File at build-time, that could
provide that info. But that info is already available in the JAR
itself.
If you want to mess with the class path (what is it that makes the class
path so attractive to mess with?), at least try to stack the cards in
your favor. E.g. place some marker file in the jar, like
"THIS-IS-MY-VERY-IMPORTANT-JAR". And use getResource() as it has been
explained to you several times to find the URL of that marker file.

that is an option. of course I could also hardcode the name of the JAR
in, but I just wanted to know if an object knows which JAR-File its
class came from. This is information the JVM *could* provide.
Obviously it doesn't.

josh
 
T

Thomas Weidenfeller

Joscha said:
well, the goal is to get an overview of all the class/package-tree in
the JAR-file.

Useless, because packages are open-ended. There is no requirement to
have all members of a package in the same jar, or in a jar at all. No
one "knows" the complete list of classes belonging to a package.
I know that I could e.g. create an XML-File at build-time, that could
provide that info. But that info is already available in the JAR
itself.

It is not. The jar only contains a list of files in it. This might or
might not be the list of all classes belonging to particular packages.
that is an option. of course I could also hardcode the name of the JAR
in, but I just wanted to know if an object knows which JAR-File its
class came from.

No, because a class does not necessarily come from a jar or a class file
at all. It can e.g. come from a byte array, or loaded via a network from
a server which just generated the byte code on the fly, pulled out of
some data base or whatever source of bits and bytes one can imagine.
This is information the JVM *could* provide.

No, because it doesn't have it. And it can't have it for all potential
sources of classes. In fact, the JVM isn't too terribly interested in
the source of some byte code at all. The JVM needs byte code in memory.
The class loaders have to deliver it, using whatever means they seem fit.

An Object knows its Class. A Class knows the ClassLoader used to load
it. The ClassLoader might or might not be able to provide information
about the origin of the byte code.

The common URLClassLoader provides information about the search path
(aka. class path) it uses to locate a class. In this search path there
might be URLs pointing to to local jar files. But still such a jar might
or might not contain all classes of a particular package.

If you need to record more information about the origin of some byte
code, implement your own class loader and record that information when
you load the byte code.

/Thomas
 

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,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top