2014-11-11 2 views
1

В моем проекте есть два пакета OSGi (A и B), которым необходимо использовать разные версии javax.activation. A требует версию 1.1.0, а B - 1.1.1.Как добавить импортные пакеты из определенной версии пакета в OSGi

По умолчанию в AEM 5.6.1 установлен пакет, который экспортирует версию 1.1.1, с которой связан A. Чтобы он использовал 1.1.0 instaed, я использовал делегирование загрузки, чтобы получить javax.activation из JRE 7 для системного пакета, который равен 1.1.0. Я устанавливаю это с помощью файла sling.properties в AEM 5.6.1.

Если я даю версию javax.activation более 1.1.1 в этом файле sling.properties, то A и B используют системную версию (хотя версия импортных пакетов указана в файле manifest.mf); но если я даю версию менее 1.1.1, оба пакета используют версию, предоставленную AEM.

Как настроить мои пакеты, чтобы использовать разные версии javax.activation для Bundle A из Bundle B?

+0

можете ли вы предоставить декларацию Import-Package из вашего манифеста? – santiagozky

ответ

1

Это может быть совершенно сложно из-за правил разрешения пучка OSGI. Просмотрите эту статью - я нашел, что это хорошее объяснение различных правил, которые применяются. В частности, проверить uses директивы: http://www.christianposta.com/blog/?p=241

Жизнь будет гораздо проще, если есть способ, как использовать ту же версию (но я знаю, что не всегда возможно).

Это из приведенной выше статьи:

Для каждого объявления пакета Import-Package, должен быть соответствующим Экспортно-пакетом с таким же пакетом

Пучки могут также прикрепить другие атрибуты к пакеты, которые он импортирует, или экспорта. Что делать, если мы добавили атрибут версии к нашему примеру:

Bundle-Name: Bundle A Import-Package: org.apache.foo; версия = "1.2.0"

Это означает, что расслоение имеет зависимость на упаковке org.apache.foo с минимальной версией 1.2.0. Да, вы правильно читали. Хотя с OSGI вы можете указать диапазон версий, если вы не указали диапазон, но скорее используют фиксированную версию, это приведет к значению «минимального» фиксированного значения. Если существует более высокая версия для того же пакета , будет использоваться более высокая версия. Так расслоение не разрешит правильно, если не будет соответствующий пакет B, который экспортирует необходимый пакет:

Bundle-Name: Bundle B Export-Package: org.apache.foo, версия = "1.2.0"

Обратите внимание, что обратное неверно ... Если Bundle B экспортируется версия 1.2.0, Bundle A не требуется указывать версию 1.2.0. Он может использовать этот импорт и решить просто отлично:

Bundle-Name: Bundle A Import-Package: org.apache.foo

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

Что произойдет, если у вас есть сценарий, где Bundle импортирует пакет и задает версия, которая обеспечивается двумя пучками:

Пачка-Имя: Bundle A Import-Package: org.apache.foo; версия = "1.2.0"

Пачка-Имя: Bundle B Экспорт-пакета: орг .apache.foo; version = "1.2.0"

Bundle-Na me: Bundle C Export-Package: org.apache.foo; version = "1.2.0"

Какой из них связывает Bundle A use? Ответ зависит от того, был ли установлен пакет (B или C). Связки, установленные первым используются , чтобы удовлетворить зависимость, когда несколько пакетов с одной и той же версии найдены

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

Bundle-Name: Bundle D Export-Package: org.apache.foo, версия = "1.3.0"

Как мы видели выше, декларация версии в Bundle A (1.2.0) означает минимальную версию 1.2.0; поэтому, если более высокая версия была доступна , тогда она выберет это (версия 1.3.0 из Bundle D в этом случае). Однако, это приводит нас к другому временному правилу разрешения расслоения : Связки, которые уже были решены, имеют более высокий преимущество, что те не разрешенное

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

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

Что делать, если у нас был такой сценарий. Bundle A экспортирует пакет, org.apache.foo, который содержит класс FooClass. FooClass имеет метод , который возвращает объект типа BarClass, но BarClass не определен в классе пространство расслоения в , он импортируется так:

1 2 3 открытый класс FooClass { общественного BarClass Execute() {.. .}}

Bundle-Name: Bundle A Import-Package: org.apache.bar; версия = "3.6.0" Экспорт-пакет: org.apache.foo, версия = "1.2.0"

До сих пор все в порядке, пока есть еще один пакет, который правильно экспортирует org.apache.bar с правильной версией.

Bundle-Name: Bundle B Экспорт-пакет: org.apache.bar, версия = "3.6.0"

Эти два пучка рассосется хорошо. Теперь, если мы устанавливаем еще два связки, Bundle C и D Bundle, которые выглядят следующим образом:

Bundle-Name: Bundle C Import-Package: org.apache.foo; версия = "1.2.0", орг .apache.bar, версия = "4.0.0"

Bundle-Name: Bundle D Export-Package: org.apache.bar, версия = "4.0.0"

Мы можем видеть, что импорт Bundle C пакет, org.apache.foo из Bundle A. Bundle C может попытаться использовать FooClass из org.apache.foo, но когда он получает возвращаемое значение, тип BarClass, что произойдет? Bundle A рассчитывает использовать версию 3.6.0 BarClass, но в комплекте C используется версия 4.0.0. Таким образом, используемые классы не являются согласованными в пакетах во время выполнения (т. Е. Вы можете столкнуться с каким-либо несоответствием или классом исключение исключения), но все будет по-прежнему разрешаться только при развертывании времени, следующего за правилами сверху. Нам нужно рассказать кому-то , что импортирует org.apache.foo, что мы используем классы из определенной версии версии org.apache.bar, и если вы хотите использовать org.apache.foo, вы должны использовать ту же версию, что мы импортируем. Это именно то, что использует директива . Давайте изменим пакет A, чтобы указать именно это:

Bundle-Name: Bundle A Import-Package: org.apache.bar; version = "3.6.0" Export-Package: org.apache.foo; version = " 1.2.0 «», использует: = org.apache.bar

Учитывая новую конфигурацию для Bundle А, пучки бы не решительность правильно сверху Bundle C не может решить, потому что это импорт org.apache.. foo, но ограничение «uses» в Bundle A указывает , что C должен использовать ту же версию, что A делает (3.6.0) для org.apache.bar, иначе пакет не будет разрешаться при попытке развертывания . это изменение версии в Bundle C для org.apache.bar будет 3.6.0.

2

Если вы хотите использовать именно версию 1.1.0 в расслоении А, чем вы должны указать его в файле манифеста элементов а:

Import-Package: javax.activation;version="[1.1.0,1.1.0]" 

Для пучка B манифеста будет:

Import-Package: javax.activation;version="[1.1.1,1.1.1]" 
Смежные вопросы