Пакет java.lang.module
Если не указано иное, передача аргумента null конструктору или методу любого класса или интерфейса этого пакета приведёт к выбрасыванию NullPointerException. Кроме того, вызов метода с массивом или коллекцией, содержащей элемент null, приведёт к NullPointerException, если не указано иное.
Разрешение зависимостей модулей
Разрешение зависимостей — это процесс вычисления зависимостей модулей друг от друга. Этот процесс происходит во время компиляции и выполнения.
Разрешение зависимостей выполняется в два этапа. На первом этапе рекурсивно перечисляются директивы 'requires' для набора корневых модулей. Если все перечисленные модули доступны для наблюдения, на втором этапе вычисляется граф читаемости. Граф читаемости отражает зависимости модулей друг от друга, которые, в свою очередь, определяют доступ через границы модулей.
Шаг 1. Рекурсивное перечисление
При рекурсивном перечислении для набора имён модулей ищутся соответствующие объявления модулей, а для каждого объявления модуля рекурсивно перечисляются:
-
имена модулей, указанные в директивах 'requires' с модификатором 'transitive', и
-
по усмотрению хост-системы — имена модулей, указанные в директивах 'requires' без модификатора 'transitive'.
Объявления модулей ищутся в наборе наблюдаемых модулей. Набор наблюдаемых модулей определяется в зависимости от реализации. В него могут входить модули с явными объявлениями (то есть с исходным файлом module-info.java или файлом module-info.class), а также модули с неявными объявлениями (то есть автоматические модули). Поскольку у автоматического модуля нет явного объявления модуля, у него нет собственных директив 'requires', хотя его имя может быть указано в директиве 'requires' явного объявления модуля.
Набор корневых модулей, имена которых служат исходными данными для этого алгоритма, определяется в зависимости от реализации. В набор корневых модулей могут входить автоматические модули.
Если этот алгоритм перечисляет хотя бы один автоматический модуль, то должны быть перечислены все наблюдаемые автоматические модули, независимо от того, указаны ли их имена в директивах 'requires' явных объявлений модулей.
Если выполняется хотя бы одно из следующих условий, разрешение зависимостей завершается неудачей:
Любой корневой модуль недоступен для наблюдения.
Любой модуль, имя которого указано в директиве 'requires' с модификатором 'transitive', недоступен для наблюдения.
По усмотрению хост-системы любой модуль, имя которого указано в директиве 'requires' без модификатора 'transitive', недоступен для наблюдения.
Алгоритм на этом этапе дважды перечисляет одно и то же имя модуля. Это указывает на цикл в директивах 'requires' независимо от модификаторов 'transitive'.
В противном случае разрешение зависимостей переходит к шагу 2.
Шаг 2. Вычисление графа читаемости
Директива 'requires' (независимо от 'transitive') выражает зависимость одного модуля от другого. Модификатор 'transitive' приводит к тому, что от этого модуля начинают зависеть и дополнительные модули. Если модуль M указывает 'requires transitive N', то M зависит от N, а любой модуль, зависящий от M, также зависит от N. Это позволяет переработать M так, чтобы часть его содержимого или всё содержимое можно было перенести в новый модуль N, не нарушая работу модулей с директивой 'requires M'.
Зависимости модулей представлены графом читаемости. Граф читаемости — это ориентированный граф, вершинами которого являются модули, перечисленные на шаге 1, а рёбра отражают читаемость между парами модулей. Рёбра задаются следующим образом:
Сначала читаемость определяется директивами 'requires' перечисленных модулей без учёта модификаторов 'transitive':
Для каждого перечисленного модуля A, указывающего 'requires' B: A «читает» B.
Каждый перечисленный автоматический модуль X «читает» все остальные перечисленные модули (считается, что у автоматического модуля есть директивы 'requires' для каждого другого перечисленного модуля).
Затем читаемость дополняется с учётом модификаторов 'transitive':
-
Для каждого перечисленного модуля A, который «читает» B:
Если B указывает 'requires transitive' C, то A также «читает» C. Это дополнение выполняется рекурсивно: поскольку A «читает» C, если C указывает 'requires transitive' D, то A также «читает» D наряду с C и B.
-
Если B является автоматическим модулем, то A «читает» все остальные перечисленные автоматические модули. (Считается, что у автоматического модуля есть директивы 'requires transitive' для каждого другого перечисленного автоматического модуля.)
Наконец, каждый модуль «читает» сам себя.
Если в графе читаемости выполняется хотя бы одно из следующих условий, разрешение зависимостей завершается неудачей:
Модуль «читает» два или более модуля с одинаковым именем. Сюда входит случай, когда модуль «читает» другой модуль с тем же именем, что и у него самого.
Два или более модуля экспортируют пакет с одинаковым именем в модуль, который «читает» оба этих модуля. Сюда входит случай, когда модуль M, содержащий пакет p, «читает» другой модуль, экспортирующий p в M.
Модуль M объявляет 'uses p.S' или 'provides p.S with ...', но пакет p не входит в модуль M и не экспортируется в M ни одним из модулей, которые M «читает».
В противном случае разрешение зависимостей завершается успешно, а его результатом является граф читаемости.
Корневые модули
Во время компиляции набор корневых модулей обычно представляет собой набор компилируемых модулей. Во время выполнения набором корневых модулей обычно является модуль приложения, указанный для средства запуска 'java'. При компиляции кода в безымянном модуле или во время выполнения, когда главный класс приложения загружается из пути классов, набор корневых модулей по умолчанию зависит от реализации. В JDK набор корневых модулей по умолчанию содержит каждый модуль в пути обновления модулей или среди системных модулей, который экспортирует хотя бы один пакет без ограничений.
Наблюдаемые модули
Набор наблюдаемых модулей как во время компиляции, так и во время выполнения определяется поиском по нескольким различным путям, а также по скомпилированным модулям, встроенным в среду. Порядок поиска следующий:
Только во время компиляции — путь модулей компиляции. Этот путь содержит определения модулей в исходной форме.
Путь обновления модулей. Этот путь содержит скомпилированные определения модулей, которые будут выбраны вместо скомпилированных определений любых модулей, допускающих обновление, присутствующих в пунктах (3) и (4). Информацию о том, какие стандартные модули допускают обновление, см. в Java SE Platform.
Системные модули — скомпилированные определения, встроенные в среду.
Путь модулей приложения. Этот путь содержит скомпилированные определения библиотечных модулей и модулей приложений.
Директивы 'requires' с модификатором 'static'
Директивы 'requires' с модификатором 'static' выражают необязательную зависимость во время выполнения. Если модуль объявляет, что он указывает 'requires static M', то для удовлетворения этой зависимости при разрешении зависимостей поиск M среди наблюдаемых модулей не выполняется. Однако если M рекурсивно перечисляется на шаге 1, то все перечисленные модули, указывающие `requires static M`, будут читать M.
В разделе Необязательные службы класса Configuration показано, как разрешение зависимостей может быть устойчивым к ситуации, когда служба предоставляется модулем, необязательным во время выполнения.
Полнота
Во время компиляции разрешение зависимостей может быть частичным: для компиляции набора модулей может не потребоваться полное транзитивное замыкание. Как минимум, граф читаемости, построенный и проверенный во время компиляции, включает компилируемые модули, их непосредственные зависимости и все неявно объявленные зависимости (requires transitive).
Во время выполнения разрешение зависимостей представляет собой аддитивный процесс. Рекурсивное перечисление на шаге 1 может выполняться относительно предыдущих разрешений, поэтому корневой модуль или модуль, указанный в директиве 'requires', не перечисляется, если он уже был перечислен при предыдущем (или родительском) разрешении. Поэтому граф читаемости, являющийся результатом разрешения, может содержать вершину для модуля, перечисленного на шаге 1, и ребро, указывающее, что этот модуль читает модуль, перечисленный при предыдущем (или родительском) разрешении.
- С версии:
- 9
| Класс | Описание |
|---|---|
| Configuration | Конфигурация, являющаяся результатом разрешения зависимостей или разрешения зависимостей со связыванием служб. |
| FindException | Выбрасывается ModuleFinder, если при поиске модуля возникает ошибка. |
| InvalidModuleDescriptorException | Выбрасывается при чтении дескриптора модуля, если дескриптор модуля имеет неверный формат или его невозможно интерпретировать как дескриптор модуля. |
| ModuleDescriptor | Дескриптор модуля. |
| ModuleDescriptor.Builder | Построитель для создания объектов ModuleDescriptor. |
| ModuleDescriptor.Exports | Пакет, экспортируемый модулем; экспорт может быть квалифицированным или неквалифицированным. |
| ModuleDescriptor.Exports.Modifier | Модификатор экспортируемого пакета. |
| ModuleDescriptor.Modifier | Модификатор модуля. |
| ModuleDescriptor.Opens | Пакет, открытый модулем; открытие может быть квалифицированным или неквалифицированным. |
| ModuleDescriptor.Opens.Modifier | Модификатор открытого пакета. |
| ModuleDescriptor.Provides | Служба, для которой модуль предоставляет одну или несколько реализаций. |
| ModuleDescriptor.Requires | Зависимость от модуля. |
| ModuleDescriptor.Requires.Modifier | Модификатор зависимости от модуля. |
| ModuleDescriptor.Version | Строка версии модуля. |
| ModuleFinder | Средство поиска модулей. |
| ModuleReader | Предоставляет доступ к содержимому модуля. |
| ModuleReference | Ссылка на содержимое модуля. |
| ResolutionException | Выбрасывается, если не удаётся разрешить набор модулей или разрешить набор модулей со связыванием служб. |
| ResolvedModule | Модуль в графе разрешённых модулей. |
© 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/module/package-summary.html