Лучшие практики для зависимостей только времени выполнения в OSGi

В соответствии с принципом открытости-закрытости я обычно разрабатываю свой Java пакеты и библиотеки таким образом, что существует общий интерфейс или пакет / библиотека API и одна или несколько реализаций (очень похожих на многие распространенные API, такие как JDBC или JAXP / SAX). Чтобы найти реализацию (или иногда несколько реализаций) в базовой библиотеке API, не нарушая OCP, я обычно использую Java ServiceLoader, или иногда сканирование пути к классам через сторонние библиотеки, такие как ClassGraph или Размышления. С точки зрения Maven реализации представлены как runtime зависимости (поскольку они нужны только во время выполнения, но не во время компиляции). Довольно стандартный материал.

Итак, теперь я хочу сделать некоторые из этих пакетов доступными в виде пакетов OSGi (с API и реализацией в отдельных пакетах), но поскольку в OSGi каждый пакет имеет свой собственный загрузчик классов, ни сканирование пути к классам, ни ServiceLoader API не будут работать для этой цели. . На первый взгляд механизм фрагментации OSGi кажется наиболее близким эквивалентом описанной выше простой Java-установки. В этом сценарии пакет API будет хостом фрагмента, а конкретные реализации будут присоединяться как фрагменты к этому пакету хоста. Поскольку хост фрагмента и все присоединенные к нему фрагменты используют один и тот же загрузчик классов, стандартные механизмы простой Java, такие как ServiceLoader или ClassGraph, вероятно, по-прежнему будут работать. Это также имело бы преимущество, заключающееся в том, что не было бы необходимости определять, работает ли библиотека / пакет в контексте OSGi или нет, и не требуются никакие зависимости каркаса OSGi.

Итак, вкратце, у меня вопрос: являются ли фрагменты правильным способом реализации зависимостей только времени выполнения в OSGi или есть лучший (или более стандартный) способ? Предпочтительно, я ищу решение, которое работает в контейнере OSGi, но не требует зависимости от самого OSGi.


person raner    schedule 01.07.2020    source источник


Ответы (1)


Отсутствие фрагментов почти всегда неверно вне переводов. Модель OSGi предполагает использование сервисов.

Тогда можно будет использовать DS. Используя bnd (в maven, gradle, ant, sbt или Bndtools), вы можете создавать компоненты. Компонент - это простой старый объект Java (POJO), снабженный инструкциями по внедрению и активации. Вы можете заставить эти компоненты принимать все зависимости в конструкторе.

Bnd-код использует аннотации для создания XML-файла, который используется во время выполнения для создания, активации, внедрения и регистрации этих компонентов. Затем это будет работать из коробки в OSGi Framework. Аннотации - это время сборки, поэтому они не создают зависимостей в вашей среде выполнения.

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

@Component
public class MyComponent implements Foo {

      final Bar bar;

      @Activate
      public MyComponent( @Reference Bar bar ) {
        this.bar = bar;
      }
      ...
}
person Peter Kriens    schedule 02.07.2020
comment
Спасибо за подробный ответ, @PeterKriens. Я совершенно забыл о декларативных службах OSGi. Предлагаемое вами решение потребует добавления хотя бы зависимости от org.osgi.service.component.annotations, но это, вероятно, приемлемый компромисс (хотя я надеялся сделать что-то большее, чем пакеты в репозитории Eclipse Orbit, то есть JAR с манифестом OSGi, которые в остальном идентичны их аналоги, не относящиеся к OSGi). - person raner; 04.07.2020
comment
Прежде чем я приму этот ответ, не могли бы вы пояснить, почему фрагменты почти всегда неверны вне переводов? Насколько я понимаю, фрагменты предназначены для расширения существующих пакетов. Например, один из моих предполагаемых вариантов использования - это базовый / API-пакет с неэффективной реализацией по умолчанию и пакет расширений, который обеспечивает более эффективное решение (которое также является более тяжелым с точки зрения зависимостей, поэтому не каждый может выбрать это вариант). Действительно ли переводы / I18N - единственное законное использование фрагментов? Каковы недостатки неправильного использования фрагментов? - person raner; 04.07.2020
comment
Фрагменты - это песни сирен для людей, выросших в грязи загрузчика классов стандартной java. Они обеспечивают узнаваемую среду, но также убивают сильную модульность OSGi. Т.е. пытается съесть твой торт и съесть его тоже. Иногда это срабатывает, но в целом я вижу в них столько страданий, потому что они открывают забор, где остальная часть системы отчаянно пытается держать их закрытыми. Есть несколько применений, но, поскольку они никогда не нужны, начните без них. - person Peter Kriens; 05.07.2020