Java 9 - В чем разница между файлами "Модули" и "JAR"?

Я изучаю Java 9 из What New в Java9, и одной из горячих тем в обсуждении является модульная JDK.

У меня есть некоторые сомнения:

  1. Являются ли модули JAR файлов?
  2. Как модуль отличается от JAR файла?

Ответ 1

Модуль: новая языковая функция, введенная в Java 9 (похожая на класс, интерфейс, пакет и т.д.), Которая состоит из набора пакетов, аналогично тому, как пакет состоит из набора типов.

JAR: формат архивного файла, который связывает код и ресурсы и который может быть загружен JVM.

Более конкретно, модуль определяется следующим образом:

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

...

Самоописание модулей выражается в его объявлении модуля, новой конструкции языка программирования Java.

...

Объявление модуля скомпилировано, по соглашению, в файл с именем module-info.class, помещенный аналогично в каталог вывода файла класса.

Модуль может быть скомпилирован в Jar файл, и в этом случае Jar файл будет помечен модульным Jar файлом:

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

Некоторые другие различия между модулем и JAR:

  1. Модулям могут потребоваться другие модули, чтобы обеспечить доступ к зависимым классам требуемым модулем. У Jar нет такой концепции зависимости.

  2. Модуль может решить, какие классы и интерфейсы должны экспортироваться в другие модули, которые этого требуют. У Jar нет такого механизма инкапсуляции.

  3. Модуль может быть скомпилирован в модульный Jar файл, но некоторые модули (например, модули JDK) скомпилированы в другой формат JMOD.

  4. Имя JAR может быть изменено. До тех пор, пока классный загрузчик JVM найдет необходимый класс в пути к классам (который может состоять из одного JAR, нескольких JAR или комбинации между каталогами или JAR), имя JAR файла может быть любым. Однако имя модуля может быть явно указано в объявлении других модулей, и такое имя определяет его и не может быть свободно изменено.

Ответ 2

Являются ли модули JAR файлов? Как модуль отличается от JAR файла?

Нет, Java-архив не является модулем.

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

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

с другой стороны (я пробовал описать это здесь ~> )

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

Это также состоит из объявления модуля, указанного с помощью module-info.java.

Каждое определение модуля либо

  • Артефакт модуля, то есть модульный JAR файл или JMOD файл, содержащий определение скомпилированного модуля, иначе

  • Каталог взорванного модуля, имя которого, по соглашению, является именем модуля и содержимым которого является "взорванное" дерево каталогов, соответствующее иерархии пакетов.

Как представлено в модульной системе, модульное изображение состоит из модулей, а не файлов JAR. Модульность предусмотрена с динамической конфигурацией с точки зрения файла Modular WAR.


Но для простоты внедрения модулей был модульный JAR файл, который был представлен в JDK9, например, для модуля, состоящего из модуля module-info.java такого, что

module com.foo.bar { }

и другие классы Java как

com/foo/bar/alpha/AlphaFactory.java
com/foo/bar/alpha/Alpha.java

Существующие инструменты уже могут создавать, обрабатывать и использовать JAR файлы. Модульный JAR файл похож на обычный JAR файл всеми возможными способами, за исключением того, что он также содержит файл module-info.class в его корневом каталоге. Модульный JAR файл для вышеуказанного com.foo.bar module, например, может содержать содержимое:

META-INF/
META-INF/MANIFEST.MF
module-info.class
com/foo/bar/alpha/AlphaFactory.class
com/foo/bar/alpha/Alpha.class
...

Модульный JAR файл может использоваться в качестве модуля, и в этом случае его файл module-info.class берется, чтобы содержать объявление модулей. Он также может быть помещен в обычный путь к классу, и в этом случае его файл module-info.class игнорируется.

Ответ 3

Строго говоря, модуль представляет собой концепцию времени выполнения. Как другие цитировали из системы "Состояние модуля":

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

Это очень похоже на JAR, но...

  1. JAR не имеют значимого представления во время выполнения
  2. JAR не являются "самоописательными", что в данном случае означает, что у них нет имени, которое интересует JVM, не может выражать зависимости или определять правильный API

Это оставляет вопрос, откуда берутся модули? Существуют различные способы, но наиболее важным для разработчиков является модульная JAR. Модульный JAR похож на простой JAR, но содержит дескриптор модуля, файл module-info.class который был скомпилирован с module-info.java. Это тот файл, который определяет имя модуля, зависимости и API.

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