Подтвердить что ты не робот

Зачем проектировать Jigsaw/JPMS?

Система управления пакетами Java всегда казалась простой и эффективной для меня. Он широко используется самим JDK. Мы использовали его для имитации концепции пространств имен и модулей.

Что такое Проект Jigsaw (aka Система Java Platform Module System), пытающийся заполнить?

С официального сайта:

Целью данного проекта является разработка и внедрение стандартного модуля системы для платформы Java SE и применять эту систему к Сама платформа и JDK.

4b9b3361

Ответ 1

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

В случае Jigsaw более грубые модули включают классы Java, пакеты и их зависимости.

Вот пример: Spring и Hibernate. Оба имеют зависимость от стороннего JAR CGLIB, но они используют разные, несовместимые версии этого JAR. Что вы можете сделать, если полагаетесь на стандартный JDK? Включая версию, которая Spring хочет перерывы в спящем режиме и наоборот.

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

Если вы построите Spring из источника GitHub, вы тоже увидите его. Они переделали структуру, поэтому она состоит из нескольких модулей: core, persistence и т.д. Вы можете выбрать минимальный набор зависимостей модулей, которые необходимы вашему приложению, и игнорировать остальные. Раньше он был единственным Spring JAR, со всеми файлами .class.

Обновление: пять лет спустя - Jigsaw может по-прежнему иметь проблемы .

Ответ 2

AFAIK План состоит в том, чтобы сделать JRE более модульной. То есть имеют меньшие банки, которые являются необязательными и/или вы можете загрузить/обновить только те функции, которые вам нужны.

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

Ответ 3

На основе Марк Рейнхольд основная речь в Devoxx Belgium, Project Jigsaw собирается для устранения двух основных болевых точек:

  • Classpath
  • Массивный монолитный JDK

Что случилось с Classpath?

Мы все знаем о JAR Hell. Этот термин описывает все различные способы, с помощью которых процесс загрузки классов может не работать. Наиболее известные ограничения пути classpath:

  • Трудно сказать, есть ли конфликты. Инструменты построения, такие как maven, могут выполнять довольно хорошую работу, основанную на именах артефактов, но если у самих артефактов есть разные имена, но одно и то же содержимое, может возникнуть конфликт.
  • Основная проблема с файлами jar заключается в том, что они не являются компонентами. Это всего лишь куча файловых контейнеров, которые будут выполняться линейно. Classpath - это способ поиска классов независимо от того, какие компоненты они находятся, какие пакеты они находятся или их предполагаемое использование.

Массивный монолитный JDK

Большая монолитная природа JDK вызывает несколько проблем:

  • Он не подходит для небольших устройств. Несмотря на то, что у небольших устройств типа IoT есть процессоры, способные запускать виртуальную машину класса SE, но у них нет памяти для хранения всего JDK, особенно когда приложение использует только небольшую часть.
  • Это даже проблема в Облаке. Cloud - это все, что нужно для оптимизации использования аппаратного обеспечения, если у вас есть тысячи изображений, содержащих весь JDK, но приложения используют только небольшую часть, это будет пустой тратой.

Модули: общее решение

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

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

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

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

JEP для выполнения

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

  • JEP 200: Модульный JDK: используйте систему Java Platform Module (JPMS) для модуляции JDK
  • JEP 201: Модульный исходный код: реорганизовать исходный код JDK в модули, улучшить систему сборки для компиляции модулей и обеспечить соблюдение границ модуля на время сборки
  • JEP 261: Система модулей: Внедрение системы Java Platform Module, как указано JSR 376, вместе со связанными с JDK изменениями и улучшениями
  • JEP 220: Модульные изображения времени выполнения: реструктурируйте изображения времени выполнения JDK и JRE для размещения модулей и повышения производительности, безопасности, и ремонтопригодность
  • JEP 260: инкапсулировать большинство внутренних API: сделать большинство внутренних API JDK недоступными по умолчанию, но оставить несколько критических, широко используемых внутренних API доступны, пока поддерживаемые замены не существуют для всех или большинства их функциональных возможностей.
  • JEP 282: jlink: Java Linker: Создать инструмент, который может собирать и оптимизировать набор модулей и их зависимостей в пользовательское время выполнения, как определено в JEP 220

Заключительные замечания

В первоначальном выпуске отчета "Состояние модуля" Марк Рейнхолд описывает конкретные цели модульной системы следующим образом:

  • Надежная конфигурация, чтобы заменить хрупкий, подверженный ошибкам механизм пути класса с помощью средств для программных компонентов для объявления явных зависимостей друг с другом вместе с
  • Сильная инкапсуляция, чтобы позволить компоненту объявлять, какой из его общедоступных типов доступен для других компонентов, а какие нет.

Эти функции помогут разработчикам приложений, разработчикам библиотек и разработчикам самой платформы Java SE непосредственно, а также косвенно, поскольку они позволят масштабируемую платформу, большую целостность платформы и улучшенную производительность.

Ответ 4

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

Изучая проблемы, мы можем проиллюстрировать мотивацию Jigsaw. (Предполагается, что мы не используем OSGi, JBoss Modules и т.д., Которые, безусловно, предлагают решения.)

Проблема 1: публика слишком публична

Рассмотрим следующие классы (предположим, что оба они общедоступны):

com.acme.foo.db.api.UserDao
com.acme.foo.db.impl.UserDaoImpl

На Foo.com мы можем решить, что наша команда должна использовать UserDao и не использовать UserDaoImpl напрямую. Тем не менее, нет способа принудительного применения этого пути в classpath.

В Jigsaw модуль содержит файл module-info.java, который позволяет нам явно указывать, что является общедоступным для других модулей. То есть, у общественности есть нюанс. Например:

// com.acme.foo.db.api.UserDao is accessible, but
// com.acme.foo.db.impl.UserDaoImpl is not 
module com.acme.foo.db {
    exports com.acme.foo.db.api;
}

Проблема 2: отражение необузданное

Учитывая классы в # 1, кто-то все еще может это сделать в Java 8:

Class c = Class.forName("com.acme.foo.db.impl.UserDaoImpl");
Object obj = c.getConstructor().newInstance();

То есть: отражение является мощным и существенным, но если его не проверять, его можно использовать для нежелательного проникновения в внутренние части модуля. У Марка Рейнхольда есть довольно тревожный пример. (Сообщение SO здесь.)

В Jigsaw сильная инкапсуляция дает возможность запретить доступ к классу, включая отражение. (Это может зависеть от настроек командной строки в ожидании пересмотренной спецификации технологий для JDK 9.) Обратите внимание, что, поскольку Jigsaw используется для самого JDK, Oracle утверждает, что это позволит команде Java быстрее внедрять внутреннюю среду платформы.

Проблема 3: путь к классу стирает архитектурные отношения

У команды обычно есть ментальная модель об отношениях между баночками. Например, foo-app.jar может использовать foo-services.jar, который использует foo-db.jar. Мы можем утверждать, что классы в foo-app.jar не должны обходить "сервисный уровень" и использовать foo-db.jar напрямую. Тем не менее, нет никакого способа обеспечить это через путь к классам. Марк Рейнхолд упоминает здесь.

Для сравнения, Jigsaw предлагает ясную и надежную модель доступности для модулей.

Проблема 4: монолитное время выполнения

Время выполнения Java находится в монолитной rt.jar. На моей машине это 60+ MB с 20k классами! В эпоху микросообщений, устройств IoT и т.д. Нежелательно иметь файлы Corba, Swing, XML и другие библиотеки на диске, если они не используются.

Jigsaw разбивает сам JDK на многие модули; например java.sql содержит знакомые классы SQL. Для этого есть несколько преимуществ, но новый инструмент jlink. Предполагая, что приложение полностью модульно, jlink создает распределяемое изображение во время выполнения, которое обрезается, чтобы содержать только указанные модули (и их зависимости). Заглядывая вперед, Oracle предвидит будущее, где модули JDK скомпилированы вовремя в собственный код. Хотя jlink является необязательным, а компиляция AOT является экспериментальной, они являются основными показателями того, куда направляется Oracle.

Проблема 5: версия

Хорошо известно, что путь к классам не позволяет использовать несколько версий одной и той же банки: например. bar-lib-1.1.jar и bar-lib-2.2.jar.

Jigsaw не решает эту проблему; Марк Рейнхолд утверждает обоснование здесь. Суть в том, что Maven, Gradle и другие инструменты представляют собой большую экосистему для управления зависимостями, а другое решение будет более вредным, чем выгодным.

Следует отметить, что другие решения (например, OSGi) действительно затрагивают эту проблему (и другие, кроме # 4).

Нижняя строка

Это некоторые ключевые моменты для Jigsaw, вызванные конкретными проблемами.

Обратите внимание, что объяснение споров между Jigsaw, OSGi, JBoss Modules и т.д. является отдельным обсуждением, которое принадлежит другому сайту Stack Exchange. Есть гораздо больше различий между решениями, чем описано здесь. Более того, был достигнут достаточный консенсус в отношении утверждения бюллетеня по пересмотру общественного обзора для JSR 376.

Ответ 5

В этой статье подробно описываются проблемы, которые обе ОСGi и JPMS/Jigsaw пытаются решить:

"Java 9, OSGi и будущее модульности" [22 SEP 2016]

Он также полностью вписывается в подходы как OSGi, так и JPMS/Jigsaw. На данный момент, по-видимому, авторы перечисляют практически никаких практических "Плюсов" для JPMS/Jigsaw по сравнению со зрелыми (16 лет) OSGi.