Ответ 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 на пути к модулю и потребовать его по имени модульной системы дает это.
Интересный бит заключается в том, что, поскольку автоматические модули считывают неназванный модуль, возможно (и я обычно рекомендую это делать), чтобы оставить его зависимости от пути к классу. Таким образом, автоматические модули действуют как мост от модуля к пути класса.
Ваши модули могут сидеть на одной стороне, требуют их прямых зависимостей в качестве автоматических модулей, а косвенные зависимости могут оставаться на другой стороне. Каждый раз, когда одна из ваших зависимостей превращается в явный модуль, он оставляет мост на модульной стороне и рисует свои прямые зависимости как автоматические модули на мосту.