Класс ModuleLayer
public final class ModuleLayer extends Object
Слой создается на основе графа модулей в Configuration и функции, сопоставляющей каждому модулю ClassLoader. Создание слоя сообщает виртуальной машине Java о классах, которые могут быть загружены из модулей, чтобы виртуальная машина Java знала, к какому модулю принадлежит каждый класс.
При создании слоя для каждого ResolvedModule в конфигурации создается объект Module. Для каждого разрешенного модуля, который read, Module reads соответствующий объект времени выполнения Module, который может находиться в том же слое или в parent слое.
Методы defineModulesWithOneLoader и defineModulesWithManyLoaders позволяют удобно создавать слой модулей, в котором все модули сопоставлены одному загрузчику классов или каждый модуль сопоставлен собственному загрузчику классов. Метод defineModules предназначен для более сложных случаев, когда модули сопоставляются пользовательским загрузчикам классов с помощью функции, переданной методу. Каждый из этих методов имеет нестатический и статический варианты. Нестатические методы создают слой, у которого вызывающий объект является родительским слоем. Статические методы предназначены для более сложных случаев, когда может быть несколько родительских слоев или когда для управления модулями в слое требуется Controller.
Виртуальная машина Java имеет как минимум один непустой слой — слой boot, который создается при запуске виртуальной машины Java. Загрузочный слой содержит модуль java.base и является единственным слоем виртуальной машины Java с модулем с именем "java.base". Модули загрузочного слоя сопоставлены загрузчику классов начальной загрузки и другим загрузчикам классов, встроенным в виртуальную машину Java. Загрузочный слой часто является parent при создании дополнительных слоев.
Каждый Module в слое создается так, чтобы он exports и opens пакеты, описанные в его ModuleDescriptor. Квалифицированные экспорты (когда пакет экспортируется набору целевых модулей, а не всем модулям) материализуются при создании слоя следующим образом:
- Если модуль
Xэкспортирует пакет вYи модуль времени выполненияModuleXчитаетModuleY, то пакет экспортируется вModuleY(который может находиться в том же слое, что иX, или в родительском слое). - Если модуль
Xэкспортирует пакет вY, а модуль времени выполненияModuleXне читаетY, то целевой модульYопределяется так, как если бы для поиска модуля в слое или его родительских слоях был вызван методfindModule. ЕслиYнайден, то пакет экспортируется экземпляруY, который был найден. ЕслиYне найден, квалифицированный экспорт игнорируется.
Квалифицированные открытия обрабатываются так же, как квалифицированные экспорты.
Как и при создании Configuration, при создании слоя к automatic модулям применяется особый подход. Виртуальная машина Java создает автоматический модуль как Module, который читает каждый безымянный
Module в виртуальной машине Java.
Если не указано иное, передача аргумента null методу этого класса приводит к выбрасыванию NullPointerException.
Пример
В этом примере создается конфигурация путем разрешения модуля с именем "myapp" с конфигурацией загрузочного слоя в качестве родительской. Затем создается новый слой с модулями из этой конфигурации. Все модули определяются одним и тем же загрузчиком классов.
ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
ModuleLayer parent = ModuleLayer.boot();
Configuration cf = parent.configuration()
.resolve(finder, ModuleFinder.of(), Set.of("myapp"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
- Начиная с:
- 9
- См. также:
Краткое описание вложенных классов
| Модификатор и тип | Класс | Описание |
|---|---|---|
static final class |
ModuleLayer.Controller |
Управляет слоем модулей. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
static ModuleLayer |
boot() |
Возвращает загрузочный слой. |
Configuration |
configuration() |
Возвращает конфигурацию этого слоя. |
ModuleLayer |
defineModules |
Создает новый слой модулей с этим слоем в качестве родительского, определяя модули из указанной Configuration в виртуальной машине Java. |
static ModuleLayer.Controller |
defineModules |
Создает новый слой модулей, определяя модули из указанной
Configuration в виртуальной машине Java. |
ModuleLayer |
defineModulesWithManyLoaders |
Создает новый слой модулей с этим слоем в качестве родительского, определяя модули из указанной Configuration в виртуальной машине Java. |
static ModuleLayer.Controller |
defineModulesWithManyLoaders |
Создает новый слой модулей, определяя модули из указанной
Configuration в виртуальной машине Java. |
ModuleLayer |
defineModulesWithOneLoader |
Создает новый слой модулей с этим слоем в качестве родительского, определяя модули из указанной Configuration в виртуальной машине Java. |
static ModuleLayer.Controller |
defineModulesWithOneLoader |
Создает новый слой модулей, определяя модули из указанной
Configuration в виртуальной машине Java. |
static ModuleLayer |
empty() |
Возвращает пустой слой. |
ClassLoader |
findLoader |
Возвращает ClassLoader для модуля с указанным именем. |
Optional |
findModule |
Возвращает модуль с указанным именем в этом слое или, если его нет в этом слое, в родительских слоях. |
Set |
modules() |
Возвращает неизменяемое множество модулей этого слоя. |
List |
parents() |
Возвращает неизменяемый список родительских слоев в порядке поиска. |
String |
toString() |
Возвращает строку с описанием этого слоя модулей. |
Подробное описание методов
defineModulesWithOneLoader
public ModuleLayer defineModulesWithOneLoader(Configuration cf, ClassLoader parentLoader)
Configuration в виртуальной машине Java. Этот метод создает один загрузчик классов и определяет в нем все модули. parent каждого загрузчика классов является указанным родительским загрузчиком классов. Этот метод работает точно так, как указано для статического метода defineModulesWithOneLoader, если вызвать его с этим слоем в качестве родительского. Иными словами, если этот слой — thisLayer, то данный метод эквивалентен вызову: ModuleLayer.defineModulesWithOneLoader(cf, List.of(thisLayer), parentLoader).layer();
- Параметры:
-
cf— конфигурация слоя -
parentLoader— родительский загрузчик классов для загрузчика классов, созданного этим методом; для загрузчика классов начальной загрузки может бытьnull - Возвращает:
- Созданный слой
- Выбрасывает:
-
IllegalArgumentException— если указанная конфигурация имеет более одного родителя или родитель конфигурации не является конфигурацией этого слоя -
LayerInstantiationException— если слой не может быть создан по какой-либо из причин, указанных для статического методаdefineModulesWithOneLoader - См. также:
defineModulesWithManyLoaders
public ModuleLayer defineModulesWithManyLoaders(Configuration cf, ClassLoader parentLoader)
Configuration в виртуальной машине Java. Каждый модуль определяется в собственном ClassLoader, созданном этим методом. parent каждого загрузчика классов является указанным родительским загрузчиком классов. Этот метод работает точно так, как указано для статического метода defineModulesWithManyLoaders, если вызвать его с этим слоем в качестве родительского. Иными словами, если этот слой — thisLayer, то данный метод эквивалентен вызову: ModuleLayer.defineModulesWithManyLoaders(cf, List.of(thisLayer), parentLoader).layer();
- Параметры:
-
cf— конфигурация слоя -
parentLoader— родительский загрузчик классов для каждого загрузчика классов, созданного этим методом; для загрузчика классов начальной загрузки может бытьnull - Возвращает:
- Созданный слой
- Выбрасывает:
-
IllegalArgumentException— если указанная конфигурация имеет более одного родителя или родитель конфигурации не является конфигурацией этого слоя -
LayerInstantiationException— если слой не может быть создан по какой-либо из причин, указанных для статического методаdefineModulesWithManyLoaders - См. также:
defineModules
public ModuleLayer defineModules(Configuration cf, Function<String, ClassLoader> clf)
Configuration в виртуальной машине Java. Каждый модуль сопоставляется по имени со своим загрузчиком классов с помощью указанной функции. Этот метод работает точно так, как указано для статического метода defineModules, если вызвать его с этим слоем в качестве родительского. Иными словами, если этот слой — thisLayer, то данный метод эквивалентен вызову: ModuleLayer.defineModules(cf, List.of(thisLayer), clf).layer();
- Параметры:
-
cf— конфигурация слоя -
clf— функция для сопоставления имени модуля с загрузчиком классов - Возвращает:
- Созданный слой
- Выбрасывает:
-
IllegalArgumentException— если указанная конфигурация имеет более одного родителя или родитель конфигурации не является конфигурацией этого слоя -
LayerInstantiationException— если слой не может быть создан по какой-либо из причин, указанных для статического методаdefineModules
defineModulesWithOneLoader
public static ModuleLayer.Controller defineModulesWithOneLoader(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
Configuration в виртуальной машине Java. Этот метод создает один загрузчик классов и определяет в нем все модули. Загрузчик классов, созданный этим методом, использует прямое делегирование при загрузке классов из модулей. При вызове метода loadClass для загрузки класса его имя пакета используется для сопоставления класса с модулем. Это может быть модуль в этом слое и, следовательно, модуль, определенный в том же загрузчике классов. Это также может быть пакет модуля в родительском слое, экспортируемый одному или нескольким модулям этого слоя. Загрузчик классов делегирует загрузку загрузчику классов соответствующего модуля и выбрасывает
ClassNotFoundException, если тот загрузчик не находит класс. Когда вызывается loadClass для загрузки классов, не сопоставленных с модулем, загрузка делегируется родительскому загрузчику классов.
Загрузчик классов, созданный этим методом, ищет ресурсы ( getResource, getResources и другие методы работы с ресурсами) во всех модулях слоя, прежде чем выполнять поиск в родительском загрузчике классов.
Попытка создать слой, в котором все модули определены одним и тем же загрузчиком классов, может завершиться неудачей по следующим причинам:
Пересекающиеся пакеты: два или более модуля в конфигурации содержат один и тот же пакет.
Разделенное делегирование: результирующему загрузчику классов пришлось бы делегировать загрузку классов из определенного пакета более чем одному загрузчику классов.
Кроме того, слой нельзя создать, если конфигурация содержит модуль с именем "java.base" или модуль содержит пакет с именем "java" либо пакет, имя которого начинается с "java.".
- Параметры:
-
cf— конфигурация слоя -
parentLayers— список родительских слоев в порядке поиска -
parentLoader— родительский загрузчик классов для загрузчика классов, созданного этим методом; для загрузчика классов начальной загрузки может бытьnull - Возвращает:
- Контроллер, управляющий созданным слоем
- Выбрасывает:
-
IllegalArgumentException— если родители указанной конфигурации не соответствуют конфигурациям родительских слоев, включая порядок -
LayerInstantiationException— если невозможно определить все модули в одном загрузчике классов по какой-либо из перечисленных выше причин - См. также:
defineModulesWithManyLoaders
public static ModuleLayer.Controller defineModulesWithManyLoaders(Configuration cf, List<ModuleLayer> parentLayers, ClassLoader parentLoader)
Configuration в виртуальной машине Java. Каждый модуль определяется в собственном ClassLoader, созданном этим методом. parent каждого загрузчика классов является указанным родительским загрузчиком классов. Загрузчики классов, созданные этим методом, используют прямое делегирование при загрузке классов из модулей. При вызове метода loadClass для загрузки класса его имя пакета используется для сопоставления класса с модулем. Пакет может находиться в модуле, определенном в этом загрузчике классов. Пакет может экспортироваться другим модулем этого слоя в модуль, определенный в этом загрузчике классов. Он также может находиться в пакете, экспортируемом модулем родительского слоя. Загрузчик классов делегирует загрузку загрузчику классов соответствующего модуля и выбрасывает ClassNotFoundException, если тот загрузчик не находит класс. Когда вызывается loadClass для загрузки класса, не сопоставленного с модулем, загрузка делегируется родительскому загрузчику классов.
Загрузчики классов, созданные этим методом, ищут ресурсы ( getResource, getResources и другие методы работы с ресурсами) в модуле, определенном в соответствующем загрузчике классов, прежде чем выполнять поиск в родительском загрузчике классов.
- Параметры:
-
cf— конфигурация слоя -
parentLayers— список родительских слоев в порядке поиска -
parentLoader— родительский загрузчик классов для каждого загрузчика классов, созданного этим методом; для загрузчика классов начальной загрузки может бытьnull - Возвращает:
- Контроллер, управляющий созданным слоем
- Выбрасывает:
-
IllegalArgumentException— если родители указанной конфигурации не соответствуют конфигурациям родительских слоев, включая порядок -
LayerInstantiationException— если слой нельзя создать, поскольку конфигурация содержит модуль с именем "java.base" или модуль содержит пакет с именем "java" либо пакет, имя которого начинается с "java." - См. также:
defineModules
public static ModuleLayer.Controller defineModules(Configuration cf, List<ModuleLayer> parentLayers, Function<String, ClassLoader> clf)
Configuration в виртуальной машине Java. Указанная функция сопоставляет каждому модулю конфигурации загрузчик классов по имени модуля. Создание слоя сообщает виртуальной машине Java о классах, которые могут быть загружены, чтобы виртуальная машина Java знала, к какому модулю принадлежит каждый класс. Делегирование между загрузчиками классов должно учитывать читаемость модулей. Во избежание взаимных блокировок при загрузке классов загрузчики классов должны быть parallel-capable. Кроме того, вызывающий этот метод для создания нового слоя должен обеспечить готовность загрузчиков классов загружать классы из этих модулей до любых попыток загрузить классы или ресурсы.
Создание слоя может завершиться неудачей по следующим причинам:
Два или более модуля с одним и тем же пакетом сопоставлены одному загрузчику классов.
Модуль сопоставлен загрузчику классов, в котором уже определен модуль с таким же именем.
Модуль сопоставлен загрузчику классов, который уже определил типы в одном из пакетов этого модуля.
Кроме того, слой нельзя создать, если конфигурация содержит модуль с именем "java.base", конфигурация содержит модуль с пакетом с именем "java" или именем пакета, начинающимся с "java.", либо функция сопоставления имени модуля с загрузчиком классов возвращает null или загрузчик классов платформы.
Если функция сопоставления имени модуля с загрузчиком классов выбрасывает ошибку или исключение времени выполнения, оно передается вызывающему этот метод.
- Примечание к API:
- Зависит от реализации, является ли создание слоя этим методом атомарной операцией. Поэтому метод может завершиться неудачей после определения в виртуальной машине Java некоторых модулей, но не всех.
- Параметры:
-
cf— конфигурация слоя -
parentLayers— список родительских слоев в порядке поиска -
clf— функция для сопоставления имени модуля с загрузчиком классов - Возвращает:
- Контроллер, управляющий созданным слоем
- Выбрасывает:
-
IllegalArgumentException— если родители указанной конфигурации не соответствуют конфигурациям родительских слоев, включая порядок -
LayerInstantiationException— если создание слоя завершилось неудачей по какой-либо из перечисленных выше причин
configuration
public Configuration configuration()
- Возвращает:
- Конфигурацию этого слоя
parents
public List<ModuleLayer> parents()
- Возвращает:
- Возможно, пустой неизменяемый список родительских слоев
modules
public Set<Module> modules()
- Возвращает:
- Возможно, пустое неизменяемое множество модулей этого слоя
findModule
public Optional<Module> findModule(String name)
findModule для каждого родительского слоя в порядке поиска до тех пор, пока модуль не будет найден или не будут проверены все родительские слои. В дереве слоев это эквивалентно поиску в глубину.- Параметры:
-
name— имя искомого модуля - Возвращает:
- Модуль с указанным именем или пустой
Optional, если модуль с таким именем отсутствует в этом слое и во всех родительских слоях
findLoader
public ClassLoader findLoader(String name)
ClassLoader для модуля с указанным именем. Если модуль с указанным именем отсутствует в этом слое, поиск выполняется в parent слоях способом, описанным в findModule.- Примечание к API:
- Этот метод не возвращает
Optional<ClassLoader>, поскольку для представления загрузчика классов начальной загрузки необходимо использовать `null`. - Параметры:
-
name— имя искомого модуля - Возвращает:
- ClassLoader, в котором определен модуль
- Выбрасывает:
-
IllegalArgumentException— если модуль с указанным именем не определен в этом слое или в любом из его родительских слоев
toString
empty
public static ModuleLayer empty()
- Возвращает:
- Пустой слой
boot
public static ModuleLayer boot()
java.base. Его родительский слой — empty.- Примечание к API:
- Во время запуска и до полной инициализации загрузочного слоя этот метод возвращает
null. - Возвращает:
- Загрузочный слой
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/ModuleLayer.html