Preferred way of loading resources in Java
Preferred way of loading resources in Java
Work out the solution according to what you want…
There are two things that getResource
/getResourceAsStream()
will get from the class it is called on…
- The class loader
- The starting location
So if you do
this.getClass().getResource(foo.txt);
it will attempt to load foo.txt from the same package as the this class and with the class loader of the this class. If you put a / in front then you are absolutely referencing the resource.
this.getClass().getResource(/x/y/z/foo.txt)
will load the resource from the class loader of this and from the x.y.z package (it will need to be in the same directory as classes in that package).
Thread.currentThread().getContextClassLoader().getResource(name)
will load with the context class loader but will not resolve the name according to any package (it must be absolutely referenced)
System.class.getResource(name)
Will load the resource with the system class loader (it would have to be absolutely referenced as well, as you wont be able to put anything into the java.lang package (the package of System).
Just take a look at the source. Also indicates that getResourceAsStream just calls openStream on the URL returned from getResource and returns that.
Well, it partly depends what you want to happen if youre actually in a derived class.
For example, suppose SuperClass
is in A.jar and SubClass
is in B.jar, and youre executing code in an instance method declared in SuperClass
but where this
refers to an instance of SubClass
. If you use this.getClass().getResource()
it will look relative to SubClass
, in B.jar. I suspect thats usually not whats required.
Personally Id probably use Foo.class.getResourceAsStream(name)
most often – if you already know the name of the resource youre after, and youre sure of where it is relative to Foo
, thats the most robust way of doing it IMO.
Of course there are times when thats not what you want, too: judge each case on its merits. Its just the I know this resource is bundled with this class is the most common one Ive run into.
Preferred way of loading resources in Java
I search three places as shown below. Comments welcome.
public URL getResource(String resource){
URL url ;
//Try with the Thread Context Loader.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader != null){
url = classLoader.getResource(resource);
if(url != null){
return url;
}
}
//Lets now try with the classloader that loaded this class.
classLoader = Loader.class.getClassLoader();
if(classLoader != null){
url = classLoader.getResource(resource);
if(url != null){
return url;
}
}
//Last ditch attempt. Get the resource from the classpath.
return ClassLoader.getSystemResource(resource);
}