views:

1979

answers:

2

What's the difference between
InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName)

and
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)

and
InputStream is = this.getClass().getResourceAsStream(fileName)


When are each one more appropriate to use than the others ?
The file that I want to read is in the classpath as my class that reads the file. My class and the file are in the same jar and packaged up in an EAR file, and deployed in WebSphere 6.1.

+11  A: 

There are subtle differences as to how the fileName you are passing is interpreted. Basically, you have 2 different methods: ClassLoader.getResourceAsStream() and Class.getResourceAsStream(). These two methods will locate the resource differently.

In Class.getResourceAsStream(path), the path is interpreted as a path local to the package of the class you are calling it from. For example calling, String.getResourceAsStream("myfile.txt") will look for a file in your classpath at the following location: "java/lang/myfile.txt". If your path starts with a '/', the it will be considered an absolute path, and will start searching from the root of the classpath. So calling String.getResourceAsStream("/myfile.txt") will look at the following location in your in your class path "./myfile.txt".

ClassLoader.getResourceAsStream(path) will consider all paths to be absolute paths. So calling String.getClassLoader.getResourceAsString("myfile.txt") and String.getClassLoader.getResourceAsString("/myfile.txt") will both look for a file in your classpath at the following location: "./myfile.txt".

Everytime I mention a location in this post, it could be a location in your filesystem itself, or inside the corresponding jar file, depending on the Class and/or ClassLoader you are loading the resource from.

In your case, you are loading the class from an Application Server, so your should use Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName) instead of this.getClass().getClassLoader().getResourceAsStream(fileName). this.getClass().getResourceAsStream() will also work.

Read this article for more detailed information about that particular problem.

LordOfThePigs
A: 

Use MyClass.class.getClassLoader().getResourceAsStream(path) to load resource associated with your code. Use MyClass.class.getResourceAsStream(path) as a shortcut, and for resources packaged within your class' package.

Use Thread.currentThread().getContextClassLoader().getResourceAsStream(path) to get resources that are part of client code, not tightly bounds to the calling code. You should be careful with this as the thread context class loader could be pointing at anything.

Tom Hawtin - tackline