2010-01-05 5 views
5

У меня возникли проблемы с поиском сервисов, которые предоставляются некоторыми пакетами OSGi, которые не активируются. Опишу ситуацию:Не удается найти услугу, потому что пакет OSGi не активирован

  • Bundle А определяет интерфейс X
  • Связки B, C, и D предоставляют услуги, которые реализуют интерфейс X
    • услуг Эти пучки регистрируются с помощью Spring DM, так что они создаются только тогда, когда пакет активирован, а Spring DM инициализирует контекст приложения, определенный в комплекте
  • Пакет A активирован и в какой-то момент запрашивает реестр услуг для служб X. Он sn't найти, потому что пучки B, C и D не были перемещены в состояние ACTIVE (они только ПОСТАНОВИЛИ).

Я не могу получить пучки B, C или D для начала и, следовательно, зарегистрировать их службы. Принуждение их к запуску путем добавления их к config.ini не является опцией, так как в приложении может быть любое количество пакетов, которые установлены в приложении (через механизм обновления, подобный p2-подобному Eclipse), который реализует интерфейс X.

Приложение это приложение RCP на базе Eclipse 3.5, использующее Spring 2.5.6 и Spring DM 1.2.1.

Как заставить эти пучки активироваться?

+0

Не могли бы вы предоставить информацию об ошибках, которые вы получили? И: Bundle A экспортирует интерфейс X, а Bundle B, C, D импортирует его, правильно? – akr

+0

Да, интерфейс X экспортируется пакетом A и импортируется B, C и D. Нет сообщений об ошибках. Запрос служб, реализующих X в реестре службы, просто возвращает пустой список. –

+0

Какова мощность, которую вы запрашиваете в 'A'? Если это «1..N», у вас есть круговая зависимость. –

ответ

6

У вас действительно есть проблема иерархии зависимостей, ваше предлагаемое хакерское решение на самом деле всего лишь групповая помощь по основной проблеме.

Что вы должны действительно рассмотреть, это архитектура вашей системы, так как эффективно то, что у вас есть, является циклической зависимостью (повторное обсуждение в комментариях вашего исходного сообщения). У вас есть (нравится это или нет) A требует услуг от (и в некотором смысле зависит от) B и C. Между тем, B и C напрямую зависят от A, и поэтому не может начать, пока не появится A.

В лучшем случае вы можете написать код в B и C, чтобы прослушать существование A, но это в лучшем случае маскирует (как я уже упоминал) основную проблему. То, что вы действительно должны рассмотреть, - это расщепление A на два пучка, назовем их A1 и A2.

А1 должен обеспечивать интерфейс, который требует B и C (зависит от). A2 должен иметь слушателей для служб B и C. При запуске, если требуются услуги B и C, должен быть запущен A1, но A2 может запускаться в любое время позже, и все должно работать.

+0

Я собираюсь опробовать ваше предложение и посмотреть, что произойдет. Благодаря! –

0

Я думаю, что нашел решение этой проблемы, хотя и чувствует себя немного хакерским.

Я столкнулся с this thread, где Адриан Колиер подразумевал, что внешний «наблюдатель связок» может нести ответственность за активацию пакетов при их установке в фреймворк.

Итак, мое решение было:

  • Добавить пользовательский заголовок для объединения B, C, и двойки соответствующих манифестов, например, «MyApp-Автостарт: истинный»
  • Создать расслоение слушателя, который отвечает когда пучок перемещаются в RESOLVED состояния, и ищет заголовок
  • Если значение заголовка является «истинным» пучок слушатель называет bundle.start()

Используя этот метод, Bundl es Я хочу начать работу, не прибегая к использованию config.ini, и они могут приходить и уходить, как им заблагорассудится, но их услуги доступны при запросе.

0

Также обратите внимание на файловую установку felix, которая отслеживает каталог для пакетов и автоматически устанавливает и запускает их. Когда файл удаляется, пакет также останавливается и удаляется.