Почему вручную подключать службы OSGi — плохая идея?

Чтобы отдать предпочтение определенным реализациям служб перед другими, я написал настраиваемую версию java.util.ServiceLoader (добавляет приоритет и включенный/отключенный флаг к реализациям через файлы настроек для кода, отличного от OSGi).

Клиент был доволен и хотел такой же настройки для реализаций службы OSGi. Разработанное решение основано на вызове getServiceReferences(Class<S> clazz, String filter) на < a href="https://osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html" rel="nofollow noreferrer">BundleContext и использует фильтр null для получения всех реализаций.

Тем не менее возиться с OSGi на таком низком уровне оставляет неприятный осадок. Там много стандартного кода (например, обязательные подтипы BundleActivator ) и используемый подход также будет мешать плавному переходу на декларативные сервисы и какой-то момент времени.

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


Итак, мой вопрос: каковы веские аргументы против этого низкоуровневого подхода? Почему вместо этого следует использовать декларативные службы?


person mike    schedule 16.11.2017    source источник
comment
Думал об использовании SERVICE_RANKING вместе с политикой ранжирования, например. стандартный код имеет рейтинг ‹ 100, код клиента (что более важно) имеет рейтинг › 1000. Возможно ли это?   -  person mike    schedule 16.11.2017


Ответы (1)


По своей сути OSGi представляет собой динамическую среду. Пакеты и услуги могут появляться и исчезать в любой момент (теоретически). Таким образом, единственный способ справиться с этой средой — реагировать на изменения, а не ждать, пока что-то произойдет.

Например, компонент декларативных служб появится, как только будут представлены все его обязательные службы, и исчезнет, ​​если один из них исчезнет. Решение, основанное на загрузчике служб или аналогичном, будет активно получать доступные службы, если такая служба является обязательной, вам придется заблокировать ее, пока она не станет доступной. Это может легко привести к взаимоблокировкам в приложении.

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

С другой стороны, если у вас есть проблема, связанная с тем, что ваше приложение должно работать как внутри, так и вне OSGi, тогда DS будет проблематичным, поскольку он полагается на присутствие OSGi. Типичными примерами являются Aapache CXF и Apache Camel. Оба не используют DS и вместо этого изобрели разные абстракции для использования в OSGi, и у обоих иногда возникают проблемы в OSGi именно из-за этого. Тем не менее, было бы трудно улучшить это, поскольку они должны работать и вне OSGi.

person Christian Schneider    schedule 16.11.2017
comment
То есть основные аргументы — это простота развертывания (включая горячую замену бандлов)? - person mike; 16.11.2017
comment
Аргумент состоит в том, что реактивный подход, такой как DS, обеспечивает стабильное поведение системы. Ручное связывание с блокировкой имеет тенденцию прерывать запуск вашей системы, когда она достигает определенной сложности (например, мертвые блокировки или тайм-ауты). - person Christian Schneider; 17.11.2017
comment
Хорошо, и как бы вы предпочли определенные реализации сервиса другим, например. реализации для конкретного клиента предпочтительнее общего кода? Есть ли решение, работающее через конфигурационные файлы? Возможно без перекомпиляции? - person mike; 17.11.2017
comment
В DS вы можете использовать свойство service.ranking для автоматического выбора службы. Но переход на новый сервис работает только для жадных ссылок. Другая возможность — использовать myRef.target в конфиге клиентского компонента DS. Это позволяет указать, какую службу выбрать, используя синтаксис фильтра ldap. - person Christian Schneider; 17.11.2017