Strange simple resource loading problem

D

Daniel

Hello out there

does somebody know why the following code delivers on line 4 a correct
instance and on line 6 a null reference? I would like to understand
this...

001 import java.util.Date;
002 public class TestLoad {
003 public static void main(String[] args) {
004 System.out.println(TestLoad.class.getResourceAsStream("News.txt"));
005 System.out.println(Date.class.getResourceAsStream("News.txt"));
006 }
007 }

Thanks
Daniel Frey
 
A

Anton Spaans

Daniel said:
Hello out there

does somebody know why the following code delivers on line 4 a correct
instance and on line 6 a null reference? I would like to understand
this...

001 import java.util.Date;
002 public class TestLoad {
003 public static void main(String[] args) {
004 System.out.println(TestLoad.class.getResourceAsStream("News.txt"));
System.out.println(Date.class.getResourceAsStream("News.txt"));
006 }
007 }

Thanks
Daniel Frey

The Date Class has been loaded by the system class loader and maybe your
TestLoad class has not (is it loaded by a proprietary classloader from the
web-server or app-server your code is running on instead)?
-- Anton.
 
D

Daniel

does somebody know why the following code delivers on line 4 a
correct
instance and on line 6 a null reference? I would like to understand
this...

001 import java.util.Date;
002 public class TestLoad {
003 public static void main(String[] args) {
004 System.out.println(TestLoad.class.getResourceAsStream("News.txt"));
005 System.out.println(Date.class.getResourceAsStream("News.txt"));
006 }
007 }

The Date Class has been loaded by the system class loader and maybe your
TestLoad class has not (is it loaded by a proprietary classloader from the
web-server or app-server your code is running on instead)?

Hi Anton

Good idea. I start the application with

java -cp .;config.jar TestLoad

where config.jar contains the file "News.txt", the base directory the
class file TestLoad.class. I think in this case it is the same
classloader. It appears to me that I do not understand classloading at
all looking at this behaviour... In my opinion (not knowing the
internals of the jdk) the Data class is loaded as soon as the import
takes place, by the same classloader as the rest.

Any ideas would be highly appreciated. I use version 1.4.2_03 and did
not test this with other versions yet. Can somebody reproduce the
problem?

Daniel
 
K

Kleopatra

Daniel said:
Hello out there

does somebody know why the following code delivers on line 4 a correct
instance and on line 6 a null reference? I would like to understand
this...

001 import java.util.Date;
002 public class TestLoad {
003 public static void main(String[] args) {
004 System.out.println(TestLoad.class.getResourceAsStream("News.txt"));
005 System.out.println(Date.class.getResourceAsStream("News.txt"));
006 }
007 }

Thanks
Daniel Frey

Classloaders are hierarchically chained and can only look "up" the
chain, that is children can find resources of parents but not the other
way round.

The standard chain is:

BootstrapClassloader <-- Extension Classloader <-- application
classloader (== classspath loader or systemclassloader). As Date is
loaded by the top-level loader, it can't see the resource defined
relativ to the application class.

For details, there's a series of articles at javaworld about it (don't
have the url handy).

Greetings
Jeanette
 
D

Daniel

Classloaders are hierarchically chained and can only look "up" the
chain, that is children can find resources of parents but not the other
way round.

The standard chain is:

BootstrapClassloader <-- Extension Classloader <-- application
classloader (== classspath loader or systemclassloader). As Date is
loaded by the top-level loader, it can't see the resource defined
relativ to the application class.

Thanks Jeanette for the tip. Do I understand right:

- The BootstraClassloader is the topmost parent?
- Date gets loaed by the BootstrapClassloader?
- The ApplicationClassloader is the one that gets completed by -cp arg?
- Date.class.getResource does *not* use the ApplicationClassloader
to lookup resources, as Date was loaded by the BootstrapClassloader?

Is there a way to add Date to the ApplicationClassloader, i.e.:

new Date().getClass().getResource(...);

?

Daniel
 
K

Kleopatra

Daniel said:
Thanks Jeanette for the tip. Do I understand right:

- The BootstraClassloader is the topmost parent?
- Date gets loaed by the BootstrapClassloader?
- The ApplicationClassloader is the one that gets completed by -cp arg?
- Date.class.getResource does *not* use the ApplicationClassloader
to lookup resources, as Date was loaded by the BootstrapClassloader?

yes to all.
Is there a way to add Date to the ApplicationClassloader, i.e.:

new Date().getClass().getResource(...);

No, except subclassing Date. But why do you want to do that?

Greetings
Jeanette
 
D

Daniel

Is there a way to add Date to the ApplicationClassloader, i.e.:
No, except subclassing Date.

Jeanette, I don't understand what is the thresholing point to
distinguish whether a class is loaded by the bootstrap or application
class loader. Let me try, and correct me if I am wrong: If my code is
within a main method, I assume that the actually running class is
originally loaded by the application class loader because it was given
on the command line, like the -cp argument. I assume further that any
other class, that is not given in the main class argument or the -cp
classpath, is only accessible by the bootloader. Why would subclassing
change that? Because the subclassed class is given in the classpath?
But why do you want to do that?

I have some problems to load a resource in the main class, even with
the actual (application) class loader. As I don't understand it too
deeply, I am experimenting around to better understand it. Do you know
in what cirumstances the application class loader might not get a
resource specified in the -cp argument?

Cheers,
Daniel
 
K

Kleopatra

Daniel said:
Jeanette, I don't understand what is the thresholing point to
distinguish whether a class is loaded by the bootstrap or application
class loader.

Basically everything in rt.jar is loader by the bootstrap, everything in
the extension dir is loaded by the extension loader and everything on
the classpath is loaded by the application loader.
Let me try, and correct me if I am wrong: If my code is
within a main method, I assume that the actually running class is
originally loaded by the application class loader because it was given
on the command line, like the -cp argument. I assume further that any
other class, that is not given in the main class argument or the -cp
classpath, is only accessible by the bootloader. Why would subclassing
change that? Because the subclassed class is given in the classpath?

main has not much to do with it, except that the its class containing it
is loaded by the application loader.
I have some problems to load a resource in the main class, even with
the actual (application) class loader.

There are subtle differences (like relative/absolute resolution of
paths) between class.getResource/classloader.getResource f.i. Or there
might be some interfering class in the extension path. Or... hard to
tell without seeing the actual setup.
As I don't understand it too
deeply, I am experimenting around to better understand it. Do you know
in what cirumstances the application class loader might not get a
resource specified in the -cp argument?

experimenting is fun sometimes - reading well-written articles about the
issues (f.i. those at javaworld), usually is a bit quicker - they are
really good and explain far better than I can :)

Greetings
Jeanette
 
D

Daniel

Thanks Jeannette for your help
experimenting is fun sometimes - reading well-written articles about the
issues (f.i. those at javaworld), usually is a bit quicker - they are
really good and explain far better than I can :)

You explain very cleanly and good. At least I have the feeling that I
understand your explanations.

Certainly you're right: "Find a way out of the ClassLoader maze" is an
article written by Vladimir Roubtsov
(http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html).
He distinguishes between three *levels* of classloaders: the system
classloader (I think that's our application classloader), the current
classloader and the context classloader (thread associated). I'll have
to dig more deeply through that article a.s.a.p. Parallel the that, I
love doing/try/reproduce/test/explore the things on my own to develop
a "feeling" for this abstract subject...

Daniel
 
D

Daniel

Thanks to suggestions and ideas of Jeanette and Anton, the resolution
of the following problem has been found. This class produces a
successfull and a failing load of the resource:

001 import java.util.Date;
002 public class TestLoad {
003 public static void main(String[] args) {
004 System.out.println(TestLoad.class.getResourceAsStream("News.txt"));
005 System.out.println(Date.class.getResourceAsStream("News.txt"));
006 }
007 }

008 >java -cp .;config.jar TestLoad
009 java.util.jar.JarVerifier$VerifierStream@cd2c3c
010 null

where config.jar contains a file in the root path called "News.txt".
By replacing the relative pathnames by an absolute one (from the point
of view of the JAR files), both resources are found successfully:

011 import java.util.Date;
012 public class TestLoad {
013 public static void main(String[] args) {
014 System.out.println(TestLoad.class.getResourceAsStream("/News.txt"));
015 System.out.println(Date.class.getResourceAsStream("/News.txt"));
016 }
017 }

018 >java -cp .;config.jar TestLoad
019 java.util.jar.JarVerifier$VerifierStream@cd2c3c
020 java.util.jar.JarVerifier$VerifierStream@13582d

I must admit, I don't understand this solution 100%, but I'm a little
happier with it. Thanks to all!

Daniel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top