Проблемы с загрузчиком классов OSGi - PullRequest
1 голос
/ 12 октября 2011

Я очень новичок в OSGi.

Я разрабатываю плагин A (пакет osgi), предположим, A , который зависит от библиотек, предположим B-1.0 и C-1.0 . Теперь, если библиотека C-1.0 зависит от библиотеки B-2.0 (Примечание: другая версия библиотеки B ). Так что мой плагин имеет две разные версии библиотеки B в своем classpath. Теперь, как я могу справиться с этой ситуацией?

Поскольку я изучал последние 4-5 дней о OSGi, он создает загрузчик классов для каждого плагина в приложении JIRA, чтобы между плагинами не возникало несоответствие версий зависимостей. Но что бы сделал разработчик, если самому плагину нужны две разные версии библиотеки jar?

Могу ли я создать два разных загрузчика классов в одном пакете osgi через OSGi, скажем, один для пакета X и другой для пакета Y?

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

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 14 октября 2011

Помните, что комплекты не зависят от других комплектов !!

Связки пакеты импорта , которые экспортируются другими комплектами.(если вы не использовали Require-Bundle, но не должны).Итак, чтобы перефразировать сценарий из вашего примера:

  • Связка A Импорт пакета org.foo.Пакет C экспортирует пакет org.foo, и OSGi связывает импорт с экспортом.Пока все хорошо.

  • Связка C также импортирует пакет org.bar.Пакет B 1.0 экспортный пакет org.bar.Поэтому OSGi соединяет их вместе, и все в порядке.

  • Теперь ... связка A также импортирует пакет org.wibble.Пакет B 2.0 экспортный пакет org.wibble.Это тоже хорошо!Пакеты B 1.0 и B 2.0 - это просто разные пакеты для OSGi, они могут быть установлены одновременно.

Поэтому, когда вы посмотрите на зависимости, как они на самом деле работают, вы обнаружите, что A вполне может импортировать код из двух разных версий B .Однако есть ограничение.Рассмотрим следующее:

  • Bundle D импортирует пакеты org.foo и org.bar v1.0 (да, пакеты имеют версии).
  • Bundle E экспортная упаковка org.foo, которая удовлетворяет импорт в D .Пакет E также импортирует пакет org.bar v2.0.
  • Некоторые другие пакеты (скажем, F v1 и F v2 ) экспортируют 2 версииorg.bar пакетов.

На самом деле этот сценарий все еще может работать. D может импортировать версию 1.0 пакета org.bar откуда-либо, а E может импортировать версию 2.0 пакета org.bar из другого места, одновременно с D импортирует пакет org.foo из E .Я лично нахожу это довольно невероятным!Но это не работает, если org.foo «использует» org.bar, где «использует» означает, что некоторые типы в org.bar видны в API org.foo.В этом случае пакет D будет открыт для двух разных копий org.bar, что недопустимо, поэтому OSGi будет препятствовать запуску пакета D , не давая ему войти в RESOLVED илиАКТИВНЫЕ состояния.

0 голосов
/ 13 октября 2011

Поскольку каждый пакет OSGi имеет свой собственный загрузчик классов, во время выполнения будет 4 пакета, а также 4 загрузчика классов (A, B-1.0, B-2.0, C-1.0).

У вас может быть две копии одного и того же класса, включенные в B (одну от 1.0 и другую от 2.0). Если вы запустите это, вы можете просто столкнуться с ClassCastException в коде A, потому что две версии классов B не совпадают.

OSGi предоставляет условие «использования» для раннего обнаружения таких ситуаций. Например, C может иметь предложения использования вроде следующего:

Export-Package: c.some.package;uses="b.some.package";version="1.0"
Import-Package: b.some.package;version="2.0"

В этом случае у вас будет более ранняя ошибка (при разрешении A), известная как конфликт использования, поскольку C накладывает ограничение для своего потребителя на приемлемую версию B.

Концептуально, единственный способ решить эту проблему - заставить потребителей B (в данном случае A и C) согласовать версию B.

0 голосов
/ 12 октября 2011

В пакете или плагине osgi у вас будет meta-inf flie, который определит, какие классы вы импортируете, если вы передадите дополнительный agrument версии = 2.0, тогда он будет использовать класс из B-2.0, если вы ничего не укажетезатем он преобразуется в тот, который сначала загружается загрузчиком классов.

т.е. import-package (C 1.0): b.some.package;версия = "2.0" или b.some.package;версия = "[2.0,4.0)"

import-пакет (A 1.0): b.some.package;версия = "1.0" или b.some.package;version = "1.0"

Надеюсь, это поможет

Anup

...