Каков предполагаемый вариант использования Bundle-Classpath в пакетах OSGI

Я пытаюсь понять предполагаемый вариант использования Bundle-Classpath в пакетах OSGI.

Вот мое понимание, пожалуйста, помогите мне понять, правильно ли это.

Допустим, я работаю над созданием пакета OSGI, который будет развернут в экосистеме других пакетов. Для пакета, над которым я работаю, нужны другие пакеты, но они не загружаются / не экспортируются в этой экосистеме, и я не могу контролировать, что экспортирует экосистема. В таком сценарии я могу поместить эти пакеты в какой-нибудь каталог (скажем, «lib»), который станет частью моего пакета. На эти пакеты также следует ссылаться из Bundle-Classpath, чтобы их можно было загрузить.

  • Это правильный вариант использования Bundle-Classpath?
  • Будут ли эти дополнительные пакеты также загружены в контейнер OSGI и будут ли экспортированные ими пакеты доступны для других пакетов?

person Parag    schedule 05.06.2013    source источник


Ответы (3)


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

Возьмем пример. Предположим, что код в моем пакете использует библиотеку, например Google Guava. У меня есть два варианта упаковки моего набора:

  1. Просто создайте мой пакет, в котором будет только мой собственный код. Пакет теперь будет иметь Import-Package операторы, которые объявляют зависимость от Guava, и любой, кто захочет развернуть мой пакет в своем приложении, также должен будет развернуть Guava.

  2. В качестве альтернативы я могу включить копию Guava в свой комплект и ссылаться на нее из моего Bundle-ClassPath. Кто бы ни развернул мой пакет, он может развернуть только мой пакет, и ему не нужно беспокоиться о том, откуда взять Guava. Фактически, наличие Guava внутри моего пакета является деталью реализации, и разработчику даже не нужно знать, что я его использую.

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

Более серьезная проблема с вариантом 2 заключается в том, что все зависимости библиотеки теперь также становятся зависимостями мои. На самом деле Guava - это редкий пример библиотеки Java без собственных зависимостей ... но многие другие библиотеки Java тянутся в огромное дерево транзитивных зависимостей. Если вы используете этот подход, скажем, с Hibernate, тогда ваш собственный пакет также будет иметь этот большой набор зависимостей. Это становится очень уродливым, очень быстро.

Поэтому будьте осторожны, чтобы не злоупотреблять _4 _ / _ 5_. Вам следует подумать об использовании его только в том случае, если зависимость (а) мала и без транзитивных зависимостей, и (б) ваш пакет использует библиотеку в качестве внутренней детали реализации, то есть она не является частью вашего общедоступного API.

ОБНОВЛЕНИЕ

Я забыл ответить на ваш второй вопрос об экспорте. Ответ - НЕТ, экспорт любых «пакетов», которые вы помещаете на свой Bundle-ClassPath, НЕ будет экспортом вашего собственного пакета. Фактически, JAR, которые мы устанавливаем Bundle-ClassPath, вообще не рассматриваются как пакеты, это просто JAR.

Вы можете выбрать экспорт пакетов, которые поступают из JAR на вашем Bundle-ClassPath, но вы должны сделать это в MANIFEST.MF вашего собственного пакета.

person Neil Bartlett    schedule 05.06.2013
comment
Благодаря тонну! Просто объяснение, которое я искал :-) - person Parag; 05.06.2013
comment
Спасибо! Отличное написание. Я хотел бы порекомендовать, пожалуйста, статью среднего размера. :) - person user2756335; 24.07.2020
comment
Спасибо, это спасло меня после того, как я часами застрял над проблемой! - person Radioo; 07.12.2020

Наиболее распространенный вариант использования этого заголовка - упаковка внешних библиотек. Допустим, у вас есть библиотека foo.jar, и вы хотите использовать ее классы в своем пакете.

Вы кладете банку в свой пучок вот так,

/
  com/company/Activator.class
  foo.jar
  META-INF/MANIFEST.MF

В вашем манифесте теперь вы можете использовать

Bundle-ClassPath: foo.jar,.

Не забудьте включить . в путь к классам, иначе вы не сможете найти классы в своем пакете.

Когда классы находятся в Bundle-ClassPath, вы можете использовать их как любой другой класс: использовать их в своем коде или экспортировать.

person Angelo van der Sijpt    schedule 05.06.2013
comment
Когда я помещаю jar (не osgi) в Bundle-Classpath, нужно ли мне включать классы, которые он импортирует, в мой оператор Import-Package? - person Parag; 05.06.2013
comment
Нет: классы обрабатываются точно так же, как и любые другие в вашем пакете. - person Angelo van der Sijpt; 05.06.2013
comment
Спасибо, тогда я думаю, что это должен быть плагин пакета Maven, который заставляет меня импортировать классы, используемые jar - person Parag; 05.06.2013
comment
Хм, не уверен. Попробуйте обновить свой вопрос фактическим макетом созданного вами пакета, манифестом и операторами maven, которые вы используете. - person Angelo van der Sijpt; 05.06.2013
comment
похоже, что плагин Maven Bundle требует импорта классов, которые входят в jar, даже если это не OSGI jar. Я копну немного глубже и обновлю свой вопрос ... спасибо! - person Parag; 05.06.2013

Я думаю, тебе здесь может быть не по себе.

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

Это означает, что когда некоторому классу пакета нужен другой класс в том же пакете, для поиска класса ищется весь путь класса пакета содержащего пакета.

Из OSGI в действии.

Рассмотрим конкретный случай. Представьте себе пакет (файл JAR) со следующей структурой:

src/a/A.class
src2/b/B.class
src3/c/C.class

если вы хотите, чтобы a.A, b.B и c.C были доступны друг другу, вам нужно будет определить src, src2 и src3 как относящиеся к пути к классам пакета. Это означает, что вам нужно добавить в свой файл манифеста следующую строку:

Bundle-ClassPath: src,src2,src3
person devoured elysium    schedule 05.06.2013