tags:

views:

165

answers:

1

Hi all, I'm having problem with class loaders. All the time.

Sometimes it works, sometimes it doesn't work.

When I started I've tested this works but not from *.jar:

URL url = AcAnalyzer.class.getResource("../stuff/resource");

//and this works even from jar file:

URL url = Acnalyzer.class.getResource("/stuff/resource");

URL url = AcAnalyzer.class.getClassLoader().getResource("stuff/resource");

//But I got into the problem with tomcat..when I need to deploy it into the tomcat I had to do this:

URL url = Thread.currentThread().getContextClassLoader().getResource("something.xml");

where something.xml has to be in WEB-INF/classes/

... url.getFile();

//The problem is that most of the time it has to work within and not within jar at the same time. Now I have test where my class is getting resource, and the jar file is used in some project deployed under the tomcat..and somehow it doesn't want to work anymore:

I'm bit puzzled about class loaders :) .. How to get this resource? And and the same time have working test.

URL url = Thread.currentThread().getContextClassLoader().getResource("com/st/resource");

    FileInputStream inputStream = new FileInputStream(url.getFile());

java.io.FileNotFoundException: file:/home/aaa/.m2/repository/com/st/module-1.1-SNAPSHOT.jar!/com/st/resource (No such file or directory)

thank you for help

+2  A: 

I'm not sure exactly what the question is in the first part, although I'd advise not using "../" in a resource path.

For the second part, if you want to load a resource you shouldn't use FileInputStream - you should use getResourceAsStream() instead of getResource().getFile(). Just load from that InputStream - there won't always be an individual file that you can load with FileInputStream.

EDIT: The two ways of referring to a resource are ClassLoader.getResource and Class.getResource (and the equivalents with the AsStream suffix). The difference between them (the only difference that I'm aware of, although there may be others) is that Class.getResource treats the given path as being relative to the package of the class that you call it on. So

ClassLoader.getResource("foo/bar/baz/test.xml")

is equivalent to

foo.bar.SomeClass.class.getResource("baz/test.xml");

As for the difference between Class.getClassLoader() and Thread.getContextClassLoader() I won't claim to have a good understanding - I suggest you ask that as a separate question.

Jon Skeet
the right question should probably be what is the difference bettween all those ways of getting a class loader and getting the resource.
thank you. you were right, even though I don't fully understand why it works with getResourceAsStream() and not with getResource().getFile().
@michal2: Because when it's a resource embedded in a jar file there *isn't* a file that you can open directly.
Jon Skeet
thank you very much for your help