Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #20077 > unrolled thread

ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream()

Started byzyng <xsli2@yahoo.com>
First post2012-12-03 11:29 -0800
Last post2012-12-04 12:57 -0800
Articles 7 — 3 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream() zyng <xsli2@yahoo.com> - 2012-12-03 11:29 -0800
    Re: ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream() markspace <-@.> - 2012-12-03 12:07 -0800
      Re: ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream() Lew <lewbloch@gmail.com> - 2012-12-03 14:04 -0800
        Re: ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream() markspace <-@.> - 2012-12-03 15:25 -0800
          Re: ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream() Lew <lewbloch@gmail.com> - 2012-12-03 20:37 -0800
    Re: ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream() zyng <xsli2@yahoo.com> - 2012-12-04 05:40 -0800
      Re: ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream() Lew <lewbloch@gmail.com> - 2012-12-04 12:57 -0800

#20077 — ClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream()

Fromzyng <xsli2@yahoo.com>
Date2012-12-03 11:29 -0800
SubjectClassLoader.getSystemResourceAsStream versus this.getClass().getResourceAsStream()
Message-ID<3c227741-7b7f-4cf8-b188-ce5268894031@googlegroups.com>
I am sure the difference between the two have been discussed well: the first one is using the System classloader and the second one is using the class loader which has loaded this class, most likely a child of System classloader, according to what I have found on the web.

The part that is painful is that the first one, the file name cannot start with "/", while the second one must start with "/". I don't understand this. If you can help me by shedding some light on this, I would greatly appreciate it.

For example, suppose I have a file "hello.txt" which locates in the directory "/abc/efg/hij/." And "/abc/efg" is on Java's classpath, so for the Java code to access "/abc/efg/hij/hello.txt" in the file system or access "hij/hello.txt" inside the JAR file:

//option 1:
InputStream is = ClassLoader.getSystemResourceAsStream("hij/hello.txt");

//option 2:
InputStream is = ResourceTools.class.getResourceAsStream("/hij/hello.txt");

The first one cannot start with "/" and the second one must start with "/". I found this is very confusing since the code between the two are already very similar looking.

Thank you very much.

[toc] | [next] | [standalone]


#20079

Frommarkspace <-@.>
Date2012-12-03 12:07 -0800
Message-ID<k9j0qj$ftg$1@dont-email.me>
In reply to#20077
On 12/3/2012 11:29 AM, zyng wrote:
> I am sure the difference between the two have been discussed well:
> the first one is using the System classloader and the second one is
> using the class loader which has loaded this class, most likely a
> child of System classloader, according to what I have found on the
> web.

First, note that there are two separate objects here, ClassLoader and 
Class.  Just because the names of their respective methods are the named 
the same, doesn't mean they do the same thing.

>
> //option 1: InputStream is =
> ClassLoader.getSystemResourceAsStream("hij/hello.txt");
>
> //option 2: InputStream is =
> ResourceTools.class.getResourceAsStream("/hij/hello.txt");

Note in the documentation of the second method call:
" This method delegates to this object's class loader. If this object 
was loaded by the bootstrap class loader, the method delegates to 
ClassLoader.getSystemResourceAsStream(java.lang.String)."

So it's different because it delegates to a different method.  I have to 
guess that the two methods are designed to do different things, in spite 
of their identical names.  I suppose this could be considered a 
"gotcha."  My advice is to consider option 2; I've never seen the first 
form in actual practice.

Why they did things this way, I have no idea.  Classloading pretty 
confusing except in trivial cases.  I think it's best to keep things as 
simple as possible when you resort to loading manually.

For extra fun, look at Thread::getContextClassLoader, which is even more 
correct than option 1 or 2 above in certain circumstances (mainly web apps).

<http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getContextClassLoader()>

[toc] | [prev] | [next] | [standalone]


#20080

FromLew <lewbloch@gmail.com>
Date2012-12-03 14:04 -0800
Message-ID<890512f9-9df6-42dd-a151-993e09912ece@googlegroups.com>
In reply to#20079
markspace wrote:
> zyng wrote:
>> I am sure the difference between the two have been discussed well:

Between the two ...?

Oh, you think the subject line is part of the post. Oops.

>> the first one is using the System classloader and the second one is

The "first one" being 'ClassLoader.getSystemResourceAsStream()'?

The "second one" being 'Class#getResourceAsStream()'?

>> using the class loader which has loaded this class, most likely a
>> child of System classloader, according to what I have found on the
>> web.
> 
> First, note that there are two separate objects here, ClassLoader and 
> Class.  Just because the names of their respective methods are the named 
> the same, doesn't mean they do the same thing.

The names of the respective methods in this case are *not* named the same!
 
'ClassLoader' also has a method 'getResourceAsStream()', which unlike 
'getSystemResourceAsStream()' is not static and does different things.

>> //option 1: InputStream is =
>> ClassLoader.getSystemResourceAsStream("hij/hello.txt");
> 
>> //option 2: InputStream is =
>> ResourceTools.class.getResourceAsStream("/hij/hello.txt");
> 
> Note in the documentation of the second method call:
> " This method delegates to this object's class loader. If this object 
> was loaded by the bootstrap class loader, the method delegates to 
> ClassLoader.getSystemResourceAsStream(java.lang.String)."
> 
> So it's different because it delegates to a different method.  I have to 

And has a different name and is documented to do different things.

> guess that the two methods are designed to do different things, in spite 
> of their identical [sic] names.  I suppose this could be considered a 
> "gotcha."  My advice is to consider option 2; I've never seen the first 
> form in actual practice.
> 
> Why they did things this way, I have no idea.  Classloading pretty 
> confusing except in trivial cases.  I think it's best to keep things as 
> simple as possible when you resort to loading manually.

The OP also said, 
> The first one cannot start with "/" and the second one must start with "/". 

Not true.

> I found this is very confusing since the code between the two are already very similar looking. 

Even more confusing since it isn't true.

And the two aren't all that similar, in that they have different names and are in different classes.

If you think that's confusing, wait until you discover 'ArrayType', 'Attribute', 'BasicAttribute' vs. 
'BasicAttributes' (even more similar than the two that confused you), 'Binding', 'Bindings', 'Boolean' vs. 
'boolean' (also more similar than what confused you), 'Bounds', 'Certificate', ...

What about the fact that the 'close()' method of 'Closeable' implementations differ from each other 
yet are all part of the same type? Ore isn't the same as 'ResultSet#close()' prior to Java 7? And is 
not at all the 'close()' of 'StreamHandler'?

'List#get()' vs. 'Map#get()' - very different.

'Date#getTime()' vs. 'Calendar#getTime()'

This is fun.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#20081

Frommarkspace <-@.>
Date2012-12-03 15:25 -0800
Message-ID<k9jcdu$jdc$1@dont-email.me>
In reply to#20080
On 12/3/2012 2:04 PM, Lew wrote:

> The names of the respective methods in this case are *not* named the
> same!
>


Huh, I totally misread that somehow.  I guess I need to pay closer 
attention.

[toc] | [prev] | [next] | [standalone]


#20085

FromLew <lewbloch@gmail.com>
Date2012-12-03 20:37 -0800
Message-ID<de4ec0f0-3168-40c1-b010-ab64f43e9f88@googlegroups.com>
In reply to#20081
markspace wrote:
> Lew wrote:
>> The names of the respective methods in this case are *not* named the
>> same!
> 
> 
> Huh, I totally misread that somehow.  I guess I need to pay closer 
> attention.

Well, the two classes do, in fact, sport a method of the same name, 'getResourceAsStream()'.

Your reply applies to those methods.

But the basis of the question is flawed - why should the same-named method in a different type
behave the same? Examples abound where they don't. Heck, two different 'Runnable' types don't
even do the same things in their 'run()' methods! And that's in the same type!

(To those who don't know me, the exclamation points are hints that I'm up to some 
rhetorical mischief.)

The fact that the original question didn't even match up same-named methods when there were 
such, and ones that do nearly the same thing at that, is bit interesting but doesn't materially 
alter the situation. Method names are not determinant of behavior in and of themselves, although 
in the case of interfaces like 'Runnable' they are indicative of a formal contract.

One really needs to turn to the API docs to resolve the original question. To make matters worse, 
there's another 'getResourceAsStream()' in the Java EE API 
<http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getResourceAsStream(java.lang.String)>
and it doesn't use 'ClassLoader' at all!

What's to explain, OP? The Javadocs tell all you need to know.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#20088

Fromzyng <xsli2@yahoo.com>
Date2012-12-04 05:40 -0800
Message-ID<26be3f32-1a52-4289-a7da-5d0e72427abd@googlegroups.com>
In reply to#20077
I have gone through the ClassLoader API doc(http://docs.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#getSystemResource(java.lang.String)) several times and still don't get a clue about it.

This post cited ClassLoader API(http://www.xyzws.com/Servletfaq/what-is-different-between-classloadergetresourceasstream-and-classgetresourceasstream/21). However, in the API doc, I cannot find any information about leading slash. I guess Sun(or Oracle) has modified the API for new version. Anyway, I cannot get the answer from ClassLoader API.

I found this post which has answered me most part:
http://www.dtumanov.com/post/3355401249/java-resource-loading

[toc] | [prev] | [next] | [standalone]


#20100

FromLew <lewbloch@gmail.com>
Date2012-12-04 12:57 -0800
Message-ID<fcf8fbd2-e3ad-45a8-b04f-00a2c73e900c@googlegroups.com>
In reply to#20088
zyng wrote:
> I have gone through the ClassLoader API doc
(http://docs.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#getSystemResource(java.lang.String))
> several times and still don't get a clue about it.

Gee, less than five minutes' online search turned up this link:
http://littletutorials.com/2008/03/26/locating-resources-in-java/

Did that article's assertions check out for you?

> This post cited ClassLoader API(http://www.xyzws.com/Servletfaq/what-is-different-between-classloadergetresourceasstream-and-classgetresourceasstream/21).
> However, in the API doc, I cannot find any information about leading slash. I guess Sun(or Oracle) has modified the API for new version. 

You guess based on what? There has to be *evidence* of such a change to make such a claim.

> Anyway, I cannot get the answer from ClassLoader API.

That does seem to be a hole in the API docs, but surely you have your answer by now.

> I found this post which has answered me most part:
> http://www.dtumanov.com/post/3355401249/java-resource-loading

In the end, a quick-and-dirty code example will answer your questions for you.

-- 
Lew

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web