ClassLoader.getResource() failure

D

David Favro

Hello all,

I am trying to access a resource in the jar file which contains the
class that I am currently executing (which is also in my classpath).
So, e.g., I'm executing a method in the class com.foo.Bar, which is
stored in the jar file baz.jar. The contents of baz.jar
(hypothetical, excluding the manifest and all that):

com/foo/Bar.class
com/foo/subDir/myFile

Now I want to access myFile as a resource. Normally, I use
ClassLoader.getResource() with just the unqualified file-name, which
works fine when the file is in the same directory as the package
containing the class that I'm executing, but in this case it isn't
(it's in a subdirectory), and no matter what I try (relative path name
(i.e. subDir/myFile), fully qualified path name (i.e.
com/foo/subDir/myFile), even the pathname preceding it with a leading
'/', Class.getResource(), ClassLoader.getSystemResource(), etc.),
getResource() comes back with null.

The docs ( http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
) say that a null return could be resource doesn't exist (it does), or
I have "inadequate privileges," but doesn't give any way to determine
which one is the problem, or what "inadequate privileges" means in
this context. I even tried granting myself AllPermission but to no
avail. Is there documentation about how this works? Sun's docs
always leave me trail-and-error-ing because they never explain the
full story (this is the perfect example). Usually I can go to the
source code to figure out how it really works when their documentation
breaks down, but in this case the code that gets resources seems not
to be distributed in source form in the SDK.

So... does anyone know if there is a permission that is needed for
this (I scanned the permission documentation and found nothing),
another reason why it might return null, or, most of all, how I could
lay my hands on the source to sun.misc.URLClassPath (apparently the
code that actually does it, and not in the standard SDK source code
distribution) so I could find out for myself?

Thanks very much in advance!
 
J

Jim Sculley

David said:
Hello all,

I am trying to access a resource in the jar file which contains the
class that I am currently executing (which is also in my classpath).
So, e.g., I'm executing a method in the class com.foo.Bar, which is
stored in the jar file baz.jar. The contents of baz.jar
(hypothetical, excluding the manifest and all that):

com/foo/Bar.class
com/foo/subDir/myFile

Now I want to access myFile as a resource. Normally, I use
ClassLoader.getResource() with just the unqualified file-name, which
works fine when the file is in the same directory as the package
containing the class that I'm executing, but in this case it isn't
(it's in a subdirectory), and no matter what I try (relative path name
(i.e. subDir/myFile), fully qualified path name (i.e.
com/foo/subDir/myFile), even the pathname preceding it with a leading
'/', Class.getResource(), ClassLoader.getSystemResource(), etc.),
getResource() comes back with null.

It shouldn't. A call like this:

getClass.getResource("subDir/myFile");

should work.

Here's an example:

======================
package foo;

import java.io.*;
import java.net.URL;

public class ResourceTest {

public ResourceTest() {
System.out.println("Testing relative path..."");

URL relativeResourceURL =
getClass.getResource("resources/some_resource");
displayResource(relativeResourceURL);
System.out.println("Testing absolute path...");
URL absoluteResourceURL =
getClass.getResource("/foo/resources/some_resource");
displayResource(absoluteResourceURL);

System.out.println("Resource access test complete");
}

private void displayResource(URL url) {
try {
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String nextLine = null;
while((nextLine = br.readLine()) != null) {
System.out.println(nextLine);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}

public static void main(String[] args) throws IOException {
new ResourceTest();
}
}
==================

The directory structure for the above code and its resource file is:

tmp
|
+--foo
|
+--ResourceTest.java
|
+--resources
+
|--some_resource



To compile, start from the 'tmp' directory:

[jim@daisy tmp]$ javac foo/*.java

Next, build the jar:

[jim@daisy tmp]$ jar -cvf test.jar foo/*
added manifest
adding: foo/resources/(in = 0) (out= 0)(stored 0%)
adding: foo/resources/some_resource(in = 15) (out= 17)(deflated -13%)
adding: foo/ResourceTest.class(in = 1058) (out= 640)(deflated 39%)
adding: foo/ResourceTest.java(in = 693) (out= 350)(deflated 49%)


Finally, test it:

[jim@daisy tmp]$ java -cp test.jar foo.ResourceTest
Testing relative path...
Hello
World!!

Testing absolute path...
Hello
World!!

Resource access test complete



If this works for you, locate the difference between your code and the
above code. There should be no need to muck about in the sun.* packages.


Jim S.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top