Есть ли необходимость переходить на модули при переходе на Java 9 + / Java 11?

80

В настоящее время мы осуществляем переход с Java 8 на Java 11. Однако обновление наших служб оказалось менее болезненным, чем мы ожидали. В основном нам нужно было только изменить номер версии в нашем build.gradleфайле, и службы были успешно запущены и работали. Мы обновили библиотеки, а также (микро) сервисы, которые используют эти библиотеки. Нет проблем до сих пор.

Есть ли вообще необходимость переходить на модули? ИМХО, это приведет к ненужным расходам. Любые предложения или дополнительные материалы для чтения приветствуются.

Чтобы прояснить, будут ли какие-либо последствия, если код Java 9+ используется без введения модулей? Может ли он, например, стать несовместимым с другим кодом?

Юнес EO
источник
10
Это тот же риск, с которым вы уже сталкивались в Java 8: попасть в «ад пути к классам».
4
В какой- то степени ответит sotms / # summary . Вы можете проверить, совпадают ли цели вашего проекта с проектом Jigsaw . Кроме того, на мой взгляд, вопрос актуальности также важен для библиотек / служб, оказывающих поддержку своим потребителям.
Наман
4
@Taschi Я не думаю, что один только ад пути к классам оправдывает переход на модульный принцип, так как весь код до Java 9 имел эту проблему, и в большинстве случаев нас это устраивало (лично никогда не было проблем с этим).
Younes EO
1
@Naman, поднимающий цели проекта Jigsaw, действительно, очень хороший аргумент.
Younes EO
8
@Younes El Ouarti, удаление "Classpath Hell" - одна из двух заявленных целей Project Jigsaw. Если вы думаете, что этого недостаточно для того, чтобы иметь дело с Jigsaw, что ж ... Я согласен с вами, и я избегаю Jigsaw, когда могу.

Ответы:

132

Нет.

Переходить на модули нет необходимости.

Никогда не было необходимости переходить на модули.

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

Вам решать, начинать ли использовать модули.

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

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

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

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

Все это не означает, что вы не столкнетесь с несколькими камнями преткновения при переходе к Java 8. Однако те, с которыми вы столкнетесь, скорее всего, не будут иметь ничего общего с модулями как таковыми . Наиболее распространенные проблемы миграции, о которых мы слышали с момента выпуска Java 9 в 2017 году, связаны с изменениями синтаксиса строки версии и удалением или инкапсуляцией внутренних API ( например , sun.misc.Base64Decoder), для которых общедоступные поддерживаемые замены имеют был доступен в течение многих лет.

Марк Рейнхольд
источник
26

Я могу только сказать вам мнение моей организации по этому поводу. Мы находимся в процессе перехода к модулям для каждого проекта, над которым мы работаем. То, что мы создаем, - это в основном микросервисы + некоторые клиентские библиотеки. Для микросервисов переход на modulesкакой-то более низкий приоритет: код там уже каким-то образом изолирован в контейнере докера, поэтому «добавление» туда модулей не кажется (нам) очень важным. Эта работа продвигается медленно, но это низкий приоритет.

С другой стороны, клиентские библиотеки - это совсем другая история. Я не могу сказать вам, какой беспорядок у нас бывает. Я объясню один момент, который раньше ненавидел jigsaw. Вы предоставляете клиентам интерфейс, которым они могут пользоваться. Автоматически , что interfaceэто public- подвергается воздействию света. Обычно то, что я делаю, - это некоторые package-privateклассы, которые не доступны клиентам, использующим этот интерфейс. Я не хочу, чтобы клиенты использовали это, это внутреннее. Звучит неплохо? Неправильно.

Первая проблема заключается в том, что когда эти package-privateклассы растут и вам нужно больше классов, единственный способ сохранить все скрытым - это создать классы в одном пакете:

  package abc:
        -- /* non-public */ Usage.java
        -- /* non-public */ HelperUsage.java
        -- /* non-public */ FactoryUsage.java
        ....

Когда он растет (в нашем случае растет), эти пакеты становятся слишком большими. Вы говорите, переход на отдельный пакет? Конечно, но тогда так HelperUsageи FactoryUsageбудет, publicи мы с самого начала старались этого избежать.

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

modulesрешает эту проблему красивым способом: publicне действительно public больше; Я могу получить friendдоступ через exports toдирективу. Это значительно упрощает жизненный цикл нашего кода и управление. И мы уходим из ада классов. Конечно maven/gradle, в основном справляйтесь с этим для нас, но когда возникает проблема, боль будет очень реальной. Могло быть много других примеров.

Тем не менее, переход (все еще) непростой. Прежде всего, все в команде должны быть согласованы; во-вторых, есть препятствия. Два самых важных, которые я до сих пор вижу: как разделить каждый модуль, в зависимости от чего конкретно? Однозначного ответа у меня пока нет. Во-вторых split-packages, «один и тот же класс экспортируется разными модулями». Если это происходит с вашими библиотеками, есть способы смягчить его; но если это внешние библиотеки ... не что легко.

Если вы зависите от jarAи jarB(отдельных модулей), но они оба экспортируют abc.def.Util, вас ждет сюрприз. Однако есть способы решить эту проблему. Как-то больно, но разрешимо.

В целом, с тех пор, как мы перешли на модули (и до сих пор делаем), наш код стал намного чище. И если ваша компания использует код прежде всего, это имеет значение. С другой стороны, я был вовлечен в компании, где старшие архитекторы считали это «слишком дорогим» и «безрезультатным».

Евгений
источник
4
Спасибо за подстрекательство! Я понимаю, что модульность сопровождается необходимыми ограничениями доступа, которых нам не хватало в предыдущих версиях. Я определенно вижу, насколько это полезно для библиотек. Если связь с сервисом осуществляется через REST / AMQP / etc. это опять же не столько проблема, точнее, плюсов нет? Может быть, мы не можем произвольно сказать, что весь код java 9+ должен быть модульным? Значит, мы должны рассматривать его как сам «инструмент»? Тем не менее интересно.
Younes EO
Что вы можете найти полезным, так это шаблон API «аксессор» (но обратите внимание, что вместо общедоступного статического поля предпочтительнее частное с методами, чтобы избежать взаимоблокировок во время загрузки класса). Смотрите здесь: wiki.netbeans.org/…
Tomáš Myšík
Спасибо, что поделились своим опытом! Было бы хорошо, если бы вы поделились более подробной информацией или ссылками на проблемы, которые вы упомянули, которые являются болезненными, но все же решаемыми.
botismarius
3
«Проблема номер два: любой пользователь / вызывающий абонент наших клиентов может создать пакет с тем же именем и расширить эти скрытые классы». Задолго до Java 9 пакеты можно было запечатать, чтобы предотвратить это. (Я считаю, что модули - отличная идея, и я использую их во всех своих проектах. Я просто хотел указать, что в данном конкретном случае они не требуются.)
VGR