You are on page 1of 5

Reflections & Reference Objects - ClassLoader.getResourceAsStream vs... http://forum.java.sun.com/thread.jspa?threadID=251367&messageID=...

Java Solaris Communities My SDN Account Join SDN

Developers Home > Developer Forums > Core > Core APIs > Reflections & Reference Objects >

Developer Forums
Reflections & Reference Objects -
ClassLoader.getResourceAsStream vs.
Class.getResourceAsStream
Sun Forums
Back to Forum Feedback About Forums
Welcome
5 Duke Stars available This topic has 1 reply on 1 page.
» Login
» Watch List
» Duke Stars Program E-mail this Topic Watch this topic
» My Forums
» Feedback
» FAQ medale94 ClassLoader.getResourceAsStream vs.
» Code of Conduct Posts:4 Class.getResourceAsStream
Registered: May 3, 2002 10:52 AM Reply »
10/29/99

Search Forums Does anyone know why the two methods are implemented with
different semantics? It seems that Class.getResourceAsStream
» supports the more intuitive absolute vs. relative path concept, while
ClassLoader.getResourceAsStream only supports absolute path
with "/" implied:

Directory structure (where classpath will be set to "classes" dir) and


content of the hello.txt file:

classes/hello.txt -> (content: File in /hello.txt)


classes/medale/test/hello.txt -> (content: File in
/medale/test/hello.txt)
classes/medale/test/medale/test/hello.txt -> (content: File in
/medale/test/medale/test/hello.txt)

All methods are executed from a class in package medale.test (see


source code and ant file below):

Using:
this.getClass().getResourceAsStream("hello.txt")

prints out:
File in /medale/test/hello.txt - File read in relative to current class
which was loaded from /medale/test

Using:
this.getClass().getResourceAsStream("/hello.txt")

prints out:
File in /hello.txt - File read using absolute path

Using:
this.getClass().getResourceAsStream("medale/test/hello.txt")

prints out:

1 of 5 2/22/2008 12:27 PM
Reflections & Reference Objects - ClassLoader.getResourceAsStream vs... http://forum.java.sun.com/thread.jspa?threadID=251367&messageID=...

File in /medale/test/medale/test/hello.txt - again relative

Using:
this.getClass().getResourceAsStream("/medale/test/hello.txt")

prints out:File in /medale/test/hello.txt - absolute path

So far - as expected however:


this.getClass().getClassLoader().getResourceAsStream("hello.txt")

Prints out:
File in /hello.txt

Using:
this.getClass().getClassLoader().getResourceAsStream("/hello.txt")

Returns null

Same with "/medale/test/hello.txt" -> null and "medale/test/hello.txt"


-> File in /medale/test/hello.txt"

Why the differing implementations?

Here is the code I used for testing this:

package medale.test;

import java.io.*;

public class CLTest {

public CLTest() throws IOException {


final String[] RES_FILES = {"hello.txt",
"/hello.txt",
"medale/test/hello.txt",
"/medale/test/hello.txt"};
System.out.println("Running code using this.getClass()."
+ "getResourceAsStream(RES_FILES)");
for (int i=0; i < RES_FILES.length; i++) {
try {
System.out.print("Result generated using file path >>"
+ RES_FILES
+"<< : ");
BufferedReader bin = new BufferedReader
(new InputStreamReader
(this.getClass().getResourceAsStream(RES_FILES)));
if (bin != null) {
System.out.println(bin.readLine());
bin.close();
} else {
System.out.println("Unable to retrieve InputStream");
}
} catch (Exception e) {
System.out.println(e);
}
}
System.out.println("\n\nRunning code using this.getClass()."
+ "getClassLoader()."
+ "getResourceAsStream(RES_FILES)");
for (int i=0; i < RES_FILES.length; i++) {
try {
System.out.print("Result generated using file path >>"
+ RES_FILES
+"<< : ");
BufferedReader bin = new BufferedReader
(new InputStreamReader

2 of 5 2/22/2008 12:27 PM
Reflections & Reference Objects - ClassLoader.getResourceAsStream vs... http://forum.java.sun.com/thread.jspa?threadID=251367&messageID=...

(this.getClass().
getClassLoader().
getResourceAsStream(RES_FILES)));
if (bin != null) {
System.out.println(bin.readLine());
bin.close();
} else {
System.out.println("Unable to retrieve InputStream");
}
} catch (Exception e) {
System.out.println(e);
}
}
System.out.println("\n\nRunning code using
Thread.currentThread()."
+ "getContextClassLoader()."
+ "getResourceAsStream(RES_FILES)");
for (int i=0; i < RES_FILES.length; i++) {
try {
System.out.print("Result generated using file path >>"
+ RES_FILES
+"<< : ");
BufferedReader bin = new BufferedReader
(new InputStreamReader
(Thread.currentThread().
getContextClassLoader().
getResourceAsStream(RES_FILES)));
if (bin != null) {
System.out.println(bin.readLine());
bin.close();
} else {
System.out.println("Unable to retrieve InputStream");
}
} catch (Exception e) {
System.out.println(e);
}
}
}

public static void main(String[] args) throws Exception {


CLTest test = new CLTest();
}
}

And here is my ant file that runs the test:

<project name="Testing" default="compile" basedir=".">


<property name="src.dir" value="src"/>
<property name="class.dir" value="classes"/>

<!-- Prepare all directories


Creates the following structure:
${class.dir}/hello.txt (content: File in /hello.txt)
${class.dir}/medale/test/hello.txt (content: File in
/medale/test/hello.txt)
${class.dir}/medale/test/medale/test/hello.txt (content: File in
/medale/test/medale/test/hello.txt)
-->
<target name="prepare">
<mkdir dir="${class.dir}/medale/test/medale/test"/>
<copy file="${src.dir}/hello.txt" todir="${class.dir}"/>
<copy file="${src.dir}/medale/test/hello.txt"
todir="${class.dir}/medale/test"/>
<copy file="${src.dir}/medale/test/medale/test/hello.txt"
todir="${class.dir}/medale/test/medale/test"/>

3 of 5 2/22/2008 12:27 PM
Reflections & Reference Objects - ClassLoader.getResourceAsStream vs... http://forum.java.sun.com/thread.jspa?threadID=251367&messageID=...

</target>

<!-- Compile all source code in src and place in classes -->
<target name="compile" depends="prepare">
<javac classpath="${class.dir}"
srcdir="${src.dir}"
destdir="${class.dir}"/>
</target>

<!-- execute Main in separate JVM -->


<target name="run" depends="compile">
<java classpath="${class.dir}"
fork="yes"
classname="medale.test.CLTest">
</java>
</target>

<target name="clean">
<delete dir="${class.dir}"/>
</target>
</project>

Any thoughts on this differing behaviour would be much


appreciated (maybe I am doing something wrong?)

Thanks,
Markus

fiontan Re: ClassLoader.getResourceAsStream vs.


Posts:761 Class.getResourceAsStream
Registered: May 4, 2002 1:49 AM (reply 1 of 1) Reply »
11/12/97

Does anyone know why the two methods are


implemented
with different semantics? It seems that
Class.getResourceAsStream supports the more
intuitive
absolute vs. relative path concept, while
ClassLoader.getResourceAsStream only supports
absolute
path with "/" implied:

Well, a Class has a path relative to which a resouce may be


located - its package. A ClassLoader simply has a findResource
method to determine where to look. Given the difference in
context, I'm not particularly surprised that the implementations
differ.

The system ClassLoader will search for the given file relative to the
system classpath... although I am surprised that including a leading
slash means that /classes/hello.txt isn't found.

I'd generally suggest that using Class.getResourceAsStream


usually makes more sense, unless you need to specifically control
where the resource is going to be located and/or which classloader
is going to load the resource.

This topic has 1 reply on 1 page.

Read the Developer Forums Code of Conduct

4 of 5 2/22/2008 12:27 PM
Reflections & Reference Objects - ClassLoader.getResourceAsStream vs... http://forum.java.sun.com/thread.jspa?threadID=251367&messageID=...

Email this Topic

Edit this Topic

About Sun | About This Site | Newsletters | Contact Us | A Sun Developer Network
Employment Site
How to Buy | Licensing | Terms of Use | Privacy | Trademarks
Unless otherwise licensed, code
in all technical manuals herein
Copyright 1994-2008 Sun Microsystems, Inc. (including articles, FAQs,
samples) is provided under this
License.
Content Feeds

5 of 5 2/22/2008 12:27 PM

You might also like