Java System Class Loader на самом деле не заменяется - PullRequest
0 голосов
/ 20 ноября 2018

Может ли класс Java System Loader действительно быть заменен?

В Java есть свойство для предположительной замены загрузчика системного класса

-Djava.system.class.loader

Однако любой класс, созданный с использованием new , а не .newInstance (), показывает AppClassLoader в качестве загрузчика классов.

AppClassLoader также известен как системный загрузчик классов, поэтому не похоже, что происходит настоящая замена.

Например, при запуске (Oracle Hotspot в Windows JDK 1.8)

// Run with java -Djava.system.class.loader=classLoaders.MyClassLoader 
public class MyClassLoader extends ClassLoader {
    public MyClassLoader(ClassLoader parent) {
        super(parent);
    }

    @Override
    public Class loadClass(String name) throws ClassNotFoundException {
        System.out.println("Loading class :" + name);
        return super.loadClass(name);
    }
};

class A
{

}

public class Example {
 public static void main(String[] args) throws Exception {
     System.out.println(ClassLoader.getSystemClassLoader());
     System.out.println(new Example().getClass().getClassLoader());
     System.out.println(new A().getClass().getClassLoader());

 }
}

Выход

Класс загрузки: classLoaders. Пример

classLoaders.MyClassLoader@6d06d69c

sun.misc.Launcher$AppClassLoader@58644d46

sun.misc.Launcher$AppClassLoader@58644d46

Пока первый экземпляр Example загружается MyClassLoader, а функция GetSystemClassLoader возвращает MyClassLoader, любой класс, созданный с помощью new , загружается исходным загрузчиком системных классов, так что именно заменяется?

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

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

После того, как загрузчик классов был успешно переопределен, он должен вызвать ваше переопределение для остальных классов.

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

0 голосов
/ 20 ноября 2018

Вы просто расширяете ClassLoader и используете super.loadClass(); Итак, какой-то другой настоящий загрузчик классов выполняет фактическую загрузку класса.

За кулисами система, похоже, делегирует загрузчик класса System после того, как вы выполняете загрузку.

Здесь на этот же вопрос уже дан ответ: https://stackoverflow.com/a/25493910/1364747

  1. MyClassLoader - начальный загрузчик классов
  2. AppClassLoader является определяющим загрузчиком классов
  3. Все классы, загруженные в один и тот же пакет, взяты из определения загрузчика классов (который фактически загрузил первый класс в пакете).

Загрузчик классов L может создать C, определив его напрямую или делегировав другому загрузчику классов. Если L создает C напрямую, мы говорим, что L определяет C или, что то же самое, что L является определяющим загрузчиком C.

Когда один загрузчик классов делегирует другому загрузчику классов, загрузчик который инициирует загрузку, не обязательно тот же загрузчик, что завершает загрузку и определяет класс. Если L создает C, либо определяя это непосредственно или делегированием, мы говорим, что L инициирует загрузку C или, что то же самое, L является инициатором загрузки C.

Во время выполнения класс или интерфейс определяется не только его именем, но парой: его двоичное имя (§4.2.1) и определяющий загрузчик классов. Каждый такой класс или интерфейс принадлежит одному пакету времени выполнения. пакет времени выполнения класса или интерфейса определяется пакетом имя и определение загрузчика класса для класса или интерфейса.

Хотя MyClassLoader вызывает super.loadClass, реализация ClassLoader-> loadClass находит только другой экземпляр и делегирует ему.

Таким образом, реализация родительского класса передает задание только другому экземпляру.

0 голосов
/ 20 ноября 2018

Вы должны переопределить метод toString () вашего MyClassLoader и посмотреть, работает ли он.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...