Загрузчик классов Java

Загрузчик классов Java , часть среды выполнения Java , динамически загружает классы Java в виртуальную машину Java . [1] Обычно классы загружаются только по требованию . Виртуальная машина будет загружать только файлы классов, необходимые для выполнения программы. [2] Системе выполнения Java не нужно знать о файлах и файловых системах, поскольку это делегировано загрузчику классов.

Библиотека программного обеспечения представляет собой набор связанного объектного кода . В языке Java библиотеки обычно упаковываются в файлы JAR . Библиотеки могут содержать объекты разных типов. Наиболее важным типом объекта, содержащегося в файле JAR, является класс Java . Класс можно рассматривать как именованную единицу кода. Загрузчик классов отвечает за поиск библиотек, чтение их содержимого и загрузку классов, содержащихся в библиотеках. Эта загрузка обычно выполняется «по требованию», то есть она не происходит до тех пор, пока класс не будет вызван программой. Класс с заданным именем может быть загружен только один раз заданным загрузчиком классов.

Каждый класс Java должен быть загружен загрузчиком классов. [3] [4] Кроме того, программы Java могут использовать внешние библиотеки (то есть библиотеки, написанные и предоставленные кем-то, кроме автора программы) или они могут состоять, по крайней мере частично, из нескольких библиотек.

При запуске JVM используются три загрузчика классов: [5] [6] [2]

  1. Загрузчик классов Bootstrap
  2. Загрузчик классов расширений
  3. Загрузчик системных классов

Загрузчик классов bootstrap загружает основные библиотеки Java [fn 1] , расположенные в каталоге <JAVA_HOME>/jre/lib(или <JAVA_HOME>/jmods>для Java 9 и выше). Этот загрузчик классов, являющийся частью основной JVM, написан на машинном коде. Загрузчик классов bootstrap не связан ни с одним ClassLoaderобъектом. [2] Например, возвращает . [2]StringBuilder.class.getClassLoader()null

Загрузчик классов расширений загружает код в каталоги расширений ( <JAVA_HOME>/jre/lib/ext, [5] или любой другой каталог, указанный системным java.ext.dirsсвойством).

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

Пользовательские загрузчики классов

Загрузчик классов Java написан на Java. Поэтому можно создать собственный загрузчик классов, не разбираясь в тонкостях виртуальной машины Java. Помимо загрузчика классов Bootstrap, каждый загрузчик классов Java имеет родительский загрузчик классов. [7] Родительский загрузчик классов определяется, когда создается новый загрузчик классов или устанавливается в качестве системного загрузчика классов виртуальной машины по умолчанию.

Это позволяет (например):

  • для загрузки или выгрузки классов во время выполнения (например, для динамической загрузки библиотек во время выполнения, даже из HTTP- ресурса). Это важная функция для:
    • реализация скриптовых языков, таких как Jython
    • использование bean- строителей
    • разрешая определяемую пользователем расширяемость
    • позволяя нескольким пространствам имен общаться. Это одна из основ протоколов CORBA / RMI , например.
  • изменить способ загрузки байт-кода (например, можно использовать зашифрованный байт-код класса Java [8] ).
  • для изменения загруженного байт-кода (например, для объединения аспектов во время загрузки при использовании аспектно-ориентированного программирования ).

Загрузчики классов в Джакарте EE

Серверы приложений Jakarta EE (ранее Java EE и J2EE) обычно загружают классы из развернутого архива WAR или EAR с помощью дерева загрузчиков классов, изолируя приложение от других приложений, но разделяя классы между развернутыми модулями. Так называемые « контейнеры сервлетов » обычно реализуются в терминах нескольких загрузчиков классов. [4] [9]

JAR ад

JAR hell — это термин, похожий на DLL hell, используемый для описания всех возможных ситуаций, в которых процесс загрузки классов может закончиться неудачей. [10] JAR hell может возникнуть тремя способами:

  • Случайное наличие двух разных версий библиотеки, установленных в системе. Это не будет считаться ошибкой системой. Вместо этого система загрузит классы из одной или другой библиотеки. Добавление новой библиотеки в список доступных библиотек вместо ее замены может привести к тому, что приложение будет по-прежнему вести себя так, как будто используется старая библиотека, что вполне может быть правдой.
  • Несколько библиотек или приложений требуют разных версий библиотеки foo . Если версии библиотеки foo используют одинаковые имена классов, нет способа загрузить версии библиотеки foo с помощью одного и того же загрузчика классов.
  • Самые сложные проблемы JAR hell возникают в обстоятельствах, которые используют всю сложность системы загрузки классов. Java-программа не обязана использовать только один "плоский" загрузчик классов, а вместо этого может состоять из нескольких (потенциально очень многих) вложенных, взаимодействующих загрузчиков классов. Классы, загруженные разными загрузчиками классов, могут взаимодействовать сложными способами, не полностью понятными разработчиком, что приводит к ошибкам или багам, которые трудно анализировать, объяснять и устранять. [11]

OSGi Alliance определил (начиная с JSR 8 в 1998 году) модульную структуру, которая направлена ​​на решение проблемы JAR-ада для текущих и будущих виртуальных машин в ME, SE и EE, которая широко принята. Используя метаданные в манифесте JAR , файлы JAR (называемые пакетами) подключаются на основе пакетов. Пакеты могут экспортировать пакеты, импортировать пакеты и сохранять пакеты приватными, предоставляя основные конструкции модульности и управления зависимостями версий.

Java 9 представила Java Platform Module System в 2017 году. Она определяет формат распределения для коллекций кода Java и связанных с ними ресурсов. Она также определяет репозиторий для хранения этих коллекций, или модулей , и определяет, как их можно обнаружить, загрузить и проверить на целостность. Она включает такие функции, как пространства имен, с целью исправления некоторых недостатков существующего формата JAR . Java Platform Module System следует философии, отличной от архитектуры OSGi, которая направлена ​​на обеспечение модульности для Java Runtime Environment обратно совместимым способом, который использует механизм загрузки классов по умолчанию, предоставляемый JRE. Однако, поскольку Java Platform Module System не предлагает возможности контролируемого сосуществования библиотек с разными версиями, она не полностью решает проблему JAR hell. [12]

Смотрите также

Сноски

  1. ^ Эти библиотеки хранятся в Jar-файлах с именами rt.jar , core.jar , server.jar и т. д.

Ссылки

  1. ^ Макманис, Чак (1 октября 1996 г.). «Основы загрузчиков классов Java». JavaWorld . Получено 13 июля 2020 г. .
  2. ^ abcd Хорстманн 2022, §10.1.1 Процесс загрузки классов.
  3. ^ Хорстманн 2022, §8.2.5 Запись байт-кодов в память.
  4. ^ ab Christudas, Binildas (26 января 2005 г.). "Внутреннее устройство загрузки классов Java". onjava.com . Архивировано из оригинала 2018-05-10.
  5. ^ ab "Понимание загрузки классов расширений". Учебники Java. docs.oracle.com . Получено 13 июля 2020 г. .
  6. ^ Сосноски, Деннис (29 апреля 2003 г.). "Классы и загрузка классов". IBM DeveloperWorks . Получено 2008-01-26 .
  7. ^ Хорстманн 2022, 10.1.2 Иерархия загрузчика классов.
  8. ^ Рубцов, Владимир (9 мая 2003 г.). «Взлом байт-кодового шифрования Java». JavaWorld . Получено 13 июля 2020 г.
  9. ^ deBoer, Tim; Karasiuk, Gary (21 августа 2002 г.). "J2EE Class Loading Demystified". IBM DeveloperWorks . Получено 26.01.2008 .
  10. ^ "Depot - Apache Incubator". Архивировано из оригинала 2013-06-01.
  11. ^ «Таксономия проблем загрузчика классов с Jakarta Commons Logging».
  12. ^ Бартлетт, Нил; Хакбарт, Кай (22.09.2016). «Java 9, OSGi и будущее модульности (часть 1)». InfoQ.
  • Чак МакМанис, «Основы загрузчиков классов Java», 1996 г.
  • Брэндон Э. Тейлор, «Загрузка классов Java: основы», архив 2020-11-09 на Wayback Machine , 2003 г.
  • Хорстманн, Кей (15 апреля 2022 г.). Ядро Java . Oracle Press Java. ISBN 0-13-787107-4.
  • Джефф Хансон, «Возьмите под контроль загрузку классов в Java», архив 2020-12-04 на Wayback Machine , 2006-06-01
  • Андреас Шефер, «Внутренние загрузчики классов», 2003-11-12
  • Шэн Лян и Гилад Брача, «Динамическая загрузка классов в виртуальной машине Java», в трудах 13-й конференции ACM по объектно-ориентированному программированию, системам, языкам и приложениям (OOPSLA'98), ACM SIGPLAN Notices, т. 33, № 10, ACM Press, 1998, стр. 36–44 doi :10.1145/286936.286945
  • Джереми Уитлок, «Реальное использование пользовательских загрузчиков классов», май 2005 г.
  • Кристоф Г. Юнг, «Загрузчики классов: новый взгляд на Hotdeploy», Информационный бюллетень Java Specialist , 2001-06-07
  • Дон Шварц, «Управление зависимостями компонентов с помощью ClassLoaders», 13 апреля 2005 г.
Получено с "https://en.wikipedia.org/w/index.php?title=Java_class_loader&oldid=1259720290"