getClass().getClassLoader() is null, why?
Asked Answered
I

9

49

I've got some code that calls..

x = getClass().getClassLoader();

This returns null though.

When I start the same code not from Eclipse, but the command line, it returns a classloader.

I can hack the code to do this...

if (getClass().getClassLoader() == null)
{
 x = ClassLoader.getSystemClassLoader().getSystemResourceAsStream( loadedPropFileName );
} 

both are compiled and run with the same JVM. (I'm 99.99% sure).

Anyone have any ideas why the first would return null for the classloader?

Edit:

My question is does "Anyone have any ideas why the same class would return null when started via Eclipse and a class loader when loaded from the command line."

Thanks for the advice that the Bootstap loader must be loading the class in Eclipse. I've no idea why this happens though.

Irrevocable answered 17/12, 2009 at 11:52 Comment(0)
S
41

Citing the API doc:

Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.

Shaitan answered 17/12, 2009 at 11:59 Comment(2)
True, but if the implementation is the same, why the different behavior in command line and Eclipse. I think this is what the OP is really asking...Laze
If he wants to know something different than what he’s asking for, why doesn’t he ask for what he really wants to know?Onassis
L
19

This is how it works . Whenever JVM try to load any class it's checks below conditions.

If Class is loaded from Bootstrap ClassPath i.e; jdk\jre\lib\rt.jar , BootStrap ClassLoader will be called.

If Class is loaded from Extension Classpath i.e; jdk\jre\lib\ext*.jar , Extension ClassLoader will be called.

If Class is loaded from Application ClassPath i.e; as specified in Environment Variable , Application ClassLoader is called .

Since Bootstrap ClassLoader is not implemented in java , it's either implemented in c or c++ so there is no reference for it that's why it returns null . But Extension and Application class Loader is written in java so you will get the reference as sun.misc.Launcher$ExtClassLoader@someHexValue and sun.misc.Launcher$AppClassLoader@someHexValue .

So, if you do something like this System.out.println(String.class.getClassLoader()) you will get null since this class is been called by BootStrap ClassLoader, On the other hand if you do the same thing for a class in Ext or App Class path you will get $ExtClassLoader@someHexValue and sun.misc.Launcher$AppClassLoader@someHexValue respectively .

Lavoie answered 26/9, 2015 at 5:22 Comment(0)
L
6

This method will return null in such implementations if this class was loaded by the bootstrap class loader.

https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getClassLoader()

Lasagne answered 17/12, 2009 at 12:0 Comment(0)
L
4

Had similar issue. Solved by not using the getClass Method. Following worked for me.

<ClassName>.class.getClassLoader();
Lair answered 28/6, 2018 at 12:3 Comment(0)
L
3

One thing is certain, Eclipse has a deeper and more complicated classloader setup than when you are running from the command line. If you are seeing differences in how a class's classloader appears in one versus the other then that is a pretty likely reason.

I'm not knowledgeable in what exactly Eclipse is doing but I think it very likely that your class is not being loaded by the bootstrap classloader when being run from Eclipse but that Eclipse is attempting to make it seem that way.

The bootstrap ClassLoader is static once the application is bootstrapped and you can't add jars or classes to it later unless Eclipse has overridden the implementation... in which case, there's yet another possible explanation.

Lucubrate answered 18/12, 2009 at 0:49 Comment(0)
G
1

The answer by @dilou points in the right direction. Check the settings of your run configuration in Eclipse: Go to the Classpath tab and check where you added the dependency. There is two categories:

  • Bootstrap Entries
  • User Entries

If a dependency is added to the first category then the bootstrap classloader is used and the problem mentioned on most of the other answers happens: It is returned as null.

So to solve the problem, move your dependency to the "User Entries" section.

Grappling answered 29/9, 2022 at 11:9 Comment(0)
E
0

I had the same issue. But solved it using :-

<ClassName>.class.getClass().getResource(urlString);

Hope this helps others...

Erdmann answered 3/10, 2013 at 16:35 Comment(0)
Y
0

"This method will return null in such implementations if this class was loaded by the bootstrap class loader." - JavaDoc at getClassLoader()

The null class loader is reserved for system classes for security purposes and can only be used if Class.forName(String name, boolean initialize, ClassLoader loader). If a class has a null ClassLoader, most security checks are not made.

Yoo answered 8/7, 2017 at 7:54 Comment(0)
B
0

It may be helpful, in order to know what Eclipse does exactly in terms of classpath setting, when launching an application, to click on the "Show Command Line" button under the application classpath setting. (I am using Eclipse 2020-06). For me, it showed that the jar file containing the class calling <ClassName>.class.getClassLoader(); which was returning null, was actually preceeded by
-Xbootclasspath/a:

Bloodstone answered 16/11, 2020 at 15:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.