getClass (). getClassLoader () является нулем, почему? - PullRequest
35 голосов
/ 17 декабря 2009

У меня есть код, который вызывает ..

x = getClass().getClassLoader();

Это возвращает ноль, хотя.

Когда я запускаю тот же код не из Eclipse, а из командной строки, он возвращает загрузчик классов.

Я могу взломать код, чтобы сделать это ...

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

оба компилируются и работают с одной и той же JVM. (Я уверен на 99,99%).

У кого-нибудь есть идеи, почему первый вернет null для загрузчика классов?

Edit:

У меня вопрос: есть ли у кого-нибудь идеи, почему один и тот же класс будет возвращать null при запуске через Eclipse и загрузчик классов при загрузке из командной строки. "

Спасибо за совет, что загрузчик Bootstap должен загружать класс в Eclipse. Я понятия не имею, почему это происходит.

Ответы [ 7 ]

32 голосов
/ 17 декабря 2009

Ссылаясь на API документ :

Некоторые реализации могут использовать нуль для представляет загрузчик класса начальной загрузки Этот метод будет возвращать ноль в такой реализации, если этот класс был загружается загрузчиком классов начальной загрузки.

8 голосов
/ 26 сентября 2015

Вот как это работает. Всякий раз, когда JVM пытается загрузить какой-либо класс, он проверяет следующие условия.

Если класс загружается из Bootstrap ClassPath i.e; jdk \ jre \ lib \ rt.jar, будет вызван BootStrap ClassLoader.

Если класс загружен из Extension Classpath i.e; jdk \ jre \ lib \ ext * .jar, будет вызываться расширение ClassLoader.

Если класс загружается из приложения ClassPath i.e; как указано в переменной среды, вызывается Application ClassLoader.

Поскольку Bootstrap ClassLoader не реализован в java, он либо реализован в c или c ++, поэтому на него нет ссылок, поэтому он возвращает ноль. Но класс расширения и приложения Loader написан на языке Java, поэтому вы получите ссылку как sun.misc.Launcher$ExtClassLoader@someHexValue и sun.misc.Launcher$AppClassLoader@someHexValue.

Итак, если вы делаете что-то подобное System.out.println (String.class.getClassLoader ()) вы получите нулевое значение, так как этот класс был вызван BootStrap ClassLoader. С другой стороны, если вы сделаете то же самое для класса в пути Ext или App Class, вы получите $ ExtClassLoader @ someHexValue и sun.misc.Launcher$AppClassLoader@someHexValue соответственно.

5 голосов
/ 17 декабря 2009

"Этот метод будет возвращать ноль в таких реализациях, если этот класс был загружен загрузчиком класса начальной загрузки." http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html#getClassLoader()

3 голосов
/ 18 декабря 2009

Одно можно сказать наверняка, Eclipse имеет более глубокую и сложную настройку загрузчика классов, чем при запуске из командной строки. Если вы видите различия в том, как классный загрузчик класса отображается в одном и другом, то это вполне вероятная причина.

Я не знаю, что именно делает Eclipse, но я думаю, что вполне вероятно, что ваш класс не загружается загрузчиком классов начальной загрузки при запуске из Eclipse, но Eclipse пытается это сделать кажется, что так.

Загрузчик ClassLoader статичен после загрузки приложения, и вы не можете добавить в него jar или классы, если только Eclipse не переопределит реализацию ... в этом случае есть еще одно возможное объяснение.

0 голосов
/ 28 июня 2018

Была похожая проблема. Решено, не используя метод getClass. Следующее сработало у меня.

<ClassName>.class.getClassLoader();
0 голосов
/ 08 июля 2017

"Этот метод будет возвращать ноль в таких реализациях, если этот класс был загружен загрузчиком класса начальной загрузки." - JavaDoc в getClassLoader ()

Загрузчик нулевого класса зарезервирован для системных классов в целях безопасности и может использоваться только в случае Class.forName (имя строки, логическая инициализация, загрузчик ClassLoader). Если класс имеет нулевой ClassLoader, большинство проверок безопасности не выполняется.

0 голосов
/ 03 октября 2013

У меня была такая же проблема. Но решил это используя: -

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

Надеюсь, что это помогает другим ...

...