Каков естественный порядок запуска пакетов OSGI, зависящих от пакетов (под Karaf)?

У меня проблема с версией Karaf 2.2.8 (и, скорее всего, с более ранними версиями тоже).

Я собираюсь использовать Karaf для размещения системы с динамически развертываемыми пакетами. Пакеты развертываются пользователями, и я не могу заранее знать, какие они.

Я ожидаю, что порядок BundleActivator.start() будет точно соответствовать зависимостям пакета между пакетами (зависимости пакетов импорта/экспорта) и планирую ожидать, что будет безопасно предположить, что пакет 0 будет полностью инициализирован до того, как пакет 1 будет запущен. . Но это не так - кажется, что BundleActivator.start() вызывается в "случайном" порядке и игнорирует зависимости пакетов между пакетами.

Пример использования, у меня есть 3 библиотеки

test-lib0 - defines testlib0.ITestRoot, exports testlib0 package 
test-lib1 - defines testlib1.TestRoot implements ITestRoot,  exports testlib1 package 
test-lib2 - uses both libs, ITestRoot and TestRoot 

Когда Karaf запускается, я вижу следующий образец вывода в консоли

karaf@root> TestLib1Activator.start() 
TestLib2Activator.start() 
        ITestRoot: interface com.testorg.testlib0.ITestRoot - 16634462 
        TestRoot:  class com.testorg.testlib1.TestRoot - 21576551 
TestLib0Activator.start() 

но я ожидаю, что это должно быть всегда в этом порядке

TestLib0Activator.start() 
TestLib1Activator.start() 
TestLib2Activator.start() 
        ITestRoot: interface com.testorg.testlib0.ITestRoot - 16634462 
        TestRoot:  class com.testorg.testlib1.TestRoot - 21576551 

Прикрепляю пример проекта для тестов. Тестовый пример: после «mvn install» просто переместите jar-файлы из папки ./deploy в ту же папку, что и Karaf, в консоли должны появиться сообщения трассировки. (Примечание: это может работать правильно с первой попытки, тогда попробуйте еще раз :))

Пример тестового проекта http://karaf.922171.n3.nabble.com/file/n4025256/KarafTest.zip

Примечание: это кросс-пост из http://karaf.922171.n3.nabble.com/What-is-the-natural-start-order-for-dependent-bundle-td4025256.html


person Xtra Coder    schedule 20.07.2012    source источник
comment
Вы сказали: я ожидаю, что порядок BundleActivator.start() будет точно соответствовать зависимостям пакетов между пакетами. Почему у вас есть такое ожидание? Это неверно, поэтому мне интересно узнать, откуда оно взялось.   -  person Neil Bartlett    schedule 20.07.2012
comment
Допустим, это ожидание исходит из макушки моей головы. Я думал, что это должно работать таким образом. После изучения спецификаций OSGI это кажется неверным ожиданием.   -  person Xtra Coder    schedule 30.07.2012


Ответы (1)


В OSGi жизненный цикл пакета составляет installed resolved starting started.

Import-Package и Export-Package влияют только тогда, когда пакет переходит с installed на resolved. Таким образом, фреймворк гарантирует, что все пакеты, из которых вы импортируете пакеты, разрешаются до вашего пакета, но затем ваш пакет переходит только в разрешенное состояние. Затем на втором этапе вызываются активаторы. Так что нельзя считать, что активаторы вызываются в одном и том же порядке. Если вам нужны некоторые инициализации, прежде чем ваш testlib2 сможет работать, вам следует использовать службы OSGi.

Итак, если я правильно понял ваш случай, то вы testlib0 определяете интерфейс, testlib1 реализует его, а testlib2 хочет использовать реализацию. Таким образом, лучший способ добиться этого — опубликовать реализацию как службу OSGi в testlib1 и сослаться на эту службу в testlib3. Затем вы можете использовать службу с помощью ServiceTracker или, например, с помощью. план. У меня есть небольшой пример, который показывает это: http://www.liquid-reality.de/x/DIBZ . Поэтому, если вы сделаете свой случай, как в моем примере, план гарантирует, что контекст testlib2 запускается только тогда, когда служба есть. Он даже остановит testlib2, когда служба исчезнет.

person Christian Schneider    schedule 20.07.2012
comment
Спасибо. Я просмотрел спецификации OSGI после вашего ответа, и да, спецификации не указывают порядок запуска в отношении зависимостей пакетов. Однако я нашел там еще одну вещь - StartLevel. У каждого бандла он от 0 (сам фреймворк) до MAX_INT. Похоже, что (по крайней мере, с Felix & Karaf) этот порядок зависит от этого StartLevel, и им можно управлять программно (через службу org.osgi.service.startlevel.StartLevel). Я создал небольшой дополнительный пакет для управления StartLevel для «моих» пакетов по мере необходимости. - person Xtra Coder; 30.07.2012
comment
Никогда не полагайтесь на начальный уровень для заказа. В OSGi любой пакет может быть обновлен/остановлен/удален в любое время. Поскольку это обходит начальные уровни, вы никогда не можете полагаться на то, что что-то есть, если только вы явно не объявите зависимость. - person Peter Kriens; 22.07.2013