Что такое автоматический модуль?

Автоматические модули многократно упоминаются в stackoverflow, но я не смог найти полное, сжатое и самодостаточное определение автоматического модуля.

Итак, что такое автоматический модуль? Он экспортирует все пакеты? Открывает ли он все пакеты? Он читает все остальные модули?

Ответ 1

Сначала я отвечу на ваш реальный вопрос ("Что такое автоматический модуль?"), Но я также объясню, для чего они предназначены. Трудно понять, почему автоматические модули ведут себя так, как они делают, без этой информации.

Что такое автоматический модуль?

Модульная система создает модуль из каждого JAR, который он находит на пути к модулю. Для модульных JAR (т.е. с дескрипторами модулей), которые являются простыми, поскольку они определяют свойства модуля (имя, требуется, экспорт). Для простых JAR (без дескриптора модуля) этот подход не работает, так что же должна делать система модуля? Он автоматически создает модуль - автоматический модуль, так сказать - и берет самые безопасные догадки для трех свойств.

название

Получение имени - это двухэтапный процесс:

  • если JAR определяет заголовок Automatic-Module-Name в своем манифесте, он определяет имя модуля
  • в противном случае имя файла JAR используется для определения имени

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

требует

Поскольку простой JAR не требует предложений, система модулей позволяет автоматическим модулям считывать все другие модули, которые превращают его в графу удобочитаемости (aka module graph). В отличие от явных модулей, автоматические также читают неназванный модуль, который содержит все, что было загружено из пути к классу. Эта, казалось бы, незначительная деталь оказывается очень важной (см. Ниже).

У автоматических модулей есть некоторые дальнейшие читательские причуды:

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

В совокупности это может привести к неудачному эффекту, что явный модуль (т.е. Неавтоматический), который зависит от нескольких простых JAR, может уйти, требуя только одного из них (пока остальные также попадают на путь модуля),

Экспорт/размыкает

Поскольку JAR не содержит информации о том, какие пакеты считаются общедоступными API, а какие нет, система модулей экспортирует все пакеты, а также открывает их для глубокого отражения.

Больше

Модульная система также сканирует META-INF/services и делает автоматический модуль предоставлением услуг, названных в нем. Предполагается, что автоматический модуль может использовать все службы.

Наконец, также обрабатывается запись манифеста Main-Class, поэтому простой JAR, который определяет один, может быть запущен точно так же, как автоматический модуль, где основной класс был установлен с помощью инструмента jar (т.е. java --module-path my-app.jar --module my.app).

Правильный модуль

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

Для чего нужен автоматический модуль?

Одной из причин внедрения модулей было сделать сборку и запуск приложений более надежными и быстрее найти ошибки, которые были возможны с помощью пути класса. Критический аспект этого requires статей.

Чтобы они были надежными, нет никакого способа, чтобы декларация модуля требовала ничего, кроме именованного модуля, который исключает все, загруженные из пути класса. Если история закончилась здесь, модульная JAR могла бы зависеть только от других модульных JAR, что заставило бы экосистему модулизоваться снизу вверх.

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

Интересный бит заключается в том, что, поскольку автоматические модули считывают неназванный модуль, возможно (и я обычно рекомендую это делать), чтобы оставить его зависимости от пути к классу. Таким образом, автоматические модули действуют как мост от модуля к пути класса.

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

Ответ 2

автоматический модуль - это именованный модуль, который определяется неявно, поскольку не имеет декларации модуля. Обычный именованный модуль, напротив, определяется явно, с объявлением модуля; мы будем отныне относятся к ним как к явным модулям.

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

Имя модуля автоматического модуля выводится из файла JAR, используемого для включения артефакта, если в его основной записи манифеста есть атрибут Автоматическое имя модуля. Имя модуля иначе выведено из имени файла JAR с помощью ModuleFinder.


Исходя из того факта, что в автоматическом модуле нет объявления модуля, практически невозможно понять, что все модули или пакеты он читает, открывает или экспортирует.

➜ Итак, поскольку нет явного экспорта/открытия для пакетов, находящихся в автоматическом модуле, описанных как

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

➜ Далее укажите ссылку -

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

Один из предложений - автоматический модуль предлагает традиционный уровень инкапсуляции: все пакеты являются открытыми для глубокого отражения доступа и экспортировать для обычного времени компиляции и времени выполнения к их общедоступным типам.


➜ Кроме того, автоматический модуль

предоставляет подразумеваемую читаемость для всех других автоматических модулей

из-за причины, что при использовании нескольких модулей в модуле его

.. нецелесообразно определить, является ли один из экспортированных пакеты в автоматическом модуле (x.y.z) содержат тип, чья подпись относится к типу, определенному в каком-либо другом автоматическом модуле (a.b.c).

Ответ 3

(Кажется, вы правы в отношении отсутствия полного определения, поскольку я не нашел его в спецификации языка или JVM)

Javadocs предоставляет множество формальных определений, хотя в классах пакетов java.lang.module.

Частичная цитата из https://docs.oracle.com/javase/9/docs/api/java/lang/module/ModuleFinder.html#automatic-modules:

Файл JAR, который не имеет module-info.class в своем каталоге верхнего уровня, определяет автоматический модуль следующим образом:

  • Если JAR файл имеет атрибут "Automatic-Module-Name" в основном манифесте, то его значением является имя модуля. Название модуля иначе выводится из имени файла JAR.

...

И из https://docs.oracle.com/javase/9/docs/api/java/lang/module/ModuleDescriptor.html:

Дескриптор модуля для автоматического модуля не объявляет никаких зависимостей (кроме обязательной зависимости от java.base) и не объявляет никаких экспортированных или открытых пакетов. Автоматический модуль получает специальную обработку во время разрешения, чтобы они считывали все остальные модули в конфигурации. Когда в виртуальной машине Java создается экземпляр автоматического модуля, он считывает каждый неназванный модуль и обрабатывается так, как будто все пакеты экспортируются и открываются.