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

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

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

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

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

Ответы

Ответ 1

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

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

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

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

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

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

Итак, вы должны быть осторожны, чтобы не злоупотреблять Bundle-ClassPath/Embed-Dependency. Вы должны использовать его только в том случае, если зависимость (а) мала и не имеет транзитивных зависимостей, и (б) ваш пакет использует библиотеку в качестве внутренней детали реализации, т.е. Она не является частью вашего публичного API.

UPDATE

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

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

Ответ 2

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

A 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. Это означало бы, что вам нужно добавить в файл манифеста следующую строку:

Bundle-ClassPath: src,src2,src3

Ответ 3

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

Вы помещаете банку в свой пакет так,

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

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

Bundle-ClassPath: foo.jar,.

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

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