Потенциальные проблемы при использовании модульной банки на пути к классам - PullRequest
2 голосов
/ 10 ноября 2019

Каковы потенциальные проблемы при использовании действительного модульного фляги (которая содержит module-info.class) на пути к классу немодульного приложения вместо на пути к модулю? На данный момент мне на ум приходят только две возможные проблемы:

  1. Случайное использование полей, методов или ресурсов из-за отсутствия инкапсуляции.
  2. Проблемы с ServiceLoader из-за отсутствия илинесовместимые декларации поставщика услуг в META-INF / services.

Существуют ли какие-либо другие потенциальные проблемы, которых я сейчас не вижу?

1 Ответ

0 голосов
/ 11 ноября 2019

Я не думаю, что какая-то из упомянутых вами вещей будет иметь место. Цитирую отрывок из книги ( Я надеюсь, что мне разрешено сделать это ) The Java Module System нашим очень уважаемым членом, @ Nicolai, на тему , как работает classpath после java 9 :

Акцент на шахте

Принимая во внимание эту обратную совместимость, остается вопрос, как система модулей работает с типами на пути классов. Короче говоря, все они попадают в безымянный модуль , который система модулей вращает на лету. Это обычный модуль, но у него есть некоторые особенности, одна из которых заключается в том, что он автоматически читает все разрешенные модули. Это также верно для модулей, которые в конечном итоге находятся на пути к классам - они будут обрабатываться так же, как простые JAR-файлы, и их типы также будут в конечном итоге в безымянном модуле, игнорируя то, что их объявление модуля должно сказать . Безымянный модуль и модули на пути к классам являются частью истории миграции, о которой подробно рассказано в разделе 8.2.

Еще раз в разделе 8.2.2

Oneдеталь, которая немного нелогична и легко ошибиться - вот что составляет безымянный модуль. Кажется очевидным, что модульные JAR-файлы становятся модулями, и, следовательно, простые JAR-файлы переходят в безымянный модуль, верно? Как объяснено в разделе 8.1.3, это неправильно: неназванный модуль отвечает за всех JAR-файлов на пути к классам , модульных или нет. Как следствие, модульные JAR-файлы не обязательно должны загружаться как модули! Если библиотека начинает предоставлять модульные JAR-файлы, ее пользователи ни в коем случае не должны использовать их в качестве модулей. Вместо этого пользователи могут оставить их в пути к классам, где их код объединен в неназванный модуль . Как более подробно объясняется в разделе 9.2, это позволяет экосистеме модулироваться практически независимо друг от друга.

Наконец, в разделе 8.1.3 говорится:

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

Заключение

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


Редактировать 2019/11/11

Службы в модульных банках должны быть объявлены в META-INF/services, а также в module-info.java, если они должны использоваться из classpath. Вот что говорится в книге:

Модульные JAR-файлы на пути к модулю - это самое лучшее место для служб в модульной системе, поэтому они работают без ограничений. Тем не менее, на пути к классам модульные JAR-файлы могут вызывать проблемы. Они обрабатываются как простые JAR-файлы, поэтому им нужны записи в папке META-INF/services. Как разработчик, чей проект опирается на сервисы и чьи модульные артефакты должны работать по обоим путям, вы должны объявить сервисы в дескрипторе модуля и META-INF/services.

...

Если модульный JAR должен предоставлять услуги, даже если он размещен в пути к классам, ему также нужны записи в каталоге META-INF / services. Для каждого обеспечения ${service} с директивой ${provider} создайте простой файл с именем ${service}, содержащий по одной строке на ${provider} (все имена должны быть полностью уточнены).

Добавление

В дополнениеИсходя из вышеизложенного, авторам библиотек с сервисами в модульных банках также необходимо объявить эти сервисы в META-INF/services, если банку нужно использовать на пути к классам.

...