Spec-Zone.ru › OpenJDK 21

Пакет java.lang.module

package 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: X "читает" каждый другой перечисленный модуль (это "как если бы" автоматический модуль имел директивы 'requires' для каждого другого перечисленного модуля).

Во-вторых, разрешимость дополняется, чтобы учесть модификаторы 'transitive':

  • Для каждого перечисленного модуля A, который "читает" B:

    • Если B 'requires transitive' C, то A "читает" C так же, как и B. Это дополнение рекурсивно: так как 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 набор корневых модулей по умолчанию содержит каждый модуль, который наблюдаем в пути к обновляемому модулю или среди системных модулей и который экспортирует по крайней мере один пакет без квалификатора.

Наблюдаемые модули

Набор наблюдаемых модулей как во время компиляции, так и во время выполнения определяется путём поиска по нескольким различным путям, а также путём поиска скомпилированных модулей, встроенных в среду. Порядок поиска следующий:

  1. Только во время компиляции — путь к модулям компиляции. Этот путь содержит определения модулей в исходном виде.

  2. Путь к обновляемым модулям. Этот путь содержит скомпилированные определения модулей, которые будут наблюдаться в приоритете перед скомпилированными определениями любых обновляемых модулей, присутствующих в (3) и (4). Смотрите Java SE Platform для обозначения того, какие стандартные модули обновляемы.

  3. Системные модули, которые являются скомпилированными определениями, встроенными в среду.

  4. Путь к модулю приложения. Этот путь содержит скомпилированные определения библиотечных и прикладных модулей.

Директивы 'requires' с модификатором 'static'

Директивы 'requires', имеющие модификатор 'static', выражают необязательную зависимость во время выполнения. Если модуль объявляет, что он 'requires static M', то разрешение не ищет наблюдаемые модули для M, чтобы удовлетворить зависимость. Однако, если M рекурсивно перечисляется на шаге 1, то все модули, которые перечисляются и 'requires static M', будут читать M.

Полнота

Разрешение может быть частичным во время компиляции, так как полное транзитивное замыкание может не потребоваться для компиляции набора модулей. Минимально, граф разрешимости, который строится и проверяется во время компиляции, включает модули, которые компилируются, их прямые зависимости и все неявно объявленные зависимости (requires transitive).

Во время выполнения разрешение является аддитивным процессом. Рекурсивное перечисление на шаге 1 может быть относительным к предыдущим разрешениям, так что корневой модуль или модуль, имя которого указано в директиве 'requires', не перечисляется, когда он уже был перечислен предыдущим (или родительским) разрешением. Граф разрешимости, являющийся результатом разрешения, может поэтому иметь вершину для модуля, перечисленного на шаге 1, но с ребром, указывающим, что модуль читает модуль, который был перечислен предыдущим (или родительским) разрешением.

Since:
9
Пакет Описание
java.lang
Предоставляет классы, являющиеся основой языка программирования Java.
Класс Описание
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, 2023, 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/21/docs/api/java.base/java/lang/module/package-summary.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API