Сплит пакеты в простой Java - PullRequest
6 голосов
/ 02 января 2009

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

Существуют ли какие-либо крайние случаи, когда разделенные пакеты могут создавать проблемы в простой Java (без OSGi)?

Просто любопытно.

Ответы [ 5 ]

14 голосов
/ 19 мая 2009

Откуда берутся сплит-пакеты

Разделение пакетов (в OSGi) происходит при использовании заголовка манифеста Require-Bundle (как я полагаю, в манифестах Eclipse). Require-Bundle называет другие пакеты, которые используются для поиска классов (если пакет не Import ed). Поиск происходит до поиска собственного пути к классам. Это позволяет загружать классы для одного пакета из экспорта нескольких пакетов (возможно, из разных jar-файлов).

Раздел 3.13 спецификации OSGi (4.1) описывает Require-Bundle и имеет длинный список (неожиданных) последствий использования этого заголовка (не рекомендуется ли этот заголовок?), Один раздел которого посвящен разделенным пакетам . Некоторые из этих последствий причудливы (и скорее специфичны для OSGi), но большинство из них можно избежать, если вы понимаете одну вещь:

  • если класс (в упаковке) предоставляется более чем одним комплектом, значит, у вас проблемы.

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

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

Что происходит в «стандартной Java»

В стандартной Java, без причудливых загрузчиков классов, у вас есть путь к классам, и порядок поиска jar-файлов (и каталогов) для загрузки классов фиксирован и четко определен: то, что вы получаете, это то, что вы получаете. (Но тогда мы отказываемся от управляемой модульности.)

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

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

Это не совсем в отличие от старой пословицы базы данных: «если вы записываете один и тот же фрагмент информации в двух местах, довольно скоро он уже не будет прежним». Наша проблема в том, что «довольно скоро» обычно не достаточно быстро.

5 голосов
/ 02 января 2009

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

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

3 голосов
/ 02 января 2009

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

3 голосов
/ 02 января 2009

Разделение пакетов по банкам, вероятно, не очень хорошая идея. Я предлагаю сделать все пакеты в банках запечатанными (поместите "Sealed: true" в основной раздел манифеста). Запечатанные пакеты нельзя разделить на банки.

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

0 голосов
/ 02 января 2009

Вы спрашиваете, потому что данный пакет принадлежит вам, а не стороннему коду?

Простым примером может служить веб-приложение с уровнями обслуживания и постоянства в виде отдельных пакетов OSGi. Постоянные интерфейсы должны совместно использоваться обоими пакетами.

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

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

...