Я работаю над приложением, которое предназначено для расширения пользователем. Он основан на OSGi (Equinox) и активно использует декларативные услуги (DS). Пакеты, установленные клиентами, предоставляют свои собственные сервисные реализации, которые затем использует мое приложение. Нет ограничений на количество реализаций услуг, которые могут предоставить пакеты, специфичные для клиента.OSGi: убедитесь, что все расширения загружены в приложении декларативных услуг
Есть ли способ гарантировать, что при выполнении основной функции приложения были зарегистрированы все службы, предоставляемые клиентом?
Для уточнения, предположим, что мое приложение состоит из одного компонента DS RunnableRunner:
public class RunnableRunner
{
private final List<Runnable> runnables = new ArrayList<Runnable>();
public void bindRunnable(Runnable runnable)
{
runnables.add(runnable);
}
public void activate()
{
System.out.println("Running runnables:");
for (Runnable runnable : runnables) {
runnable.run();
}
System.out.println("Done running runnables.");
}
}
Этот компонент регистрируется с помощью component.xml DS, таких как следующие:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="RunnableRunner" activate="activate">
<implementation class="RunnableRunner"/>
<reference bind="bindRunnable" interface="java.lang.Runnable" name="Runnable"
cardinality="0..n" policy="dynamic"/>
</scr:component>
I понимаем, что нет гарантии, что в момент времени вызывается activate()
, все Управляемые были связаны. Фактически, эксперименты, выполненные с помощью Eclipse/Equinox, указывают на то, что время выполнения DS не сможет связывать Runnables, внесенные другим пакетом, если этот пул запускает после основного пакета (что является вероятностью 50/50, если только явное начало уровни используются).
Итак, какие альтернативы мне доступны? Как я могу убедиться, что контейнеры OSGi стараются изо всех сил решить все зависимости до активации RunnableRunner?
Альтернативы я уже думал о том:
- Bundle начинают уровни: слишком грубые (они работают на уровне связки, а не на уровне компонентов), а также ненадежных (они только приняты как намек по OSGi)
- Исправление к точкам расширения Eclipse: слишком специфичное для Eclipse, трудно сочетающееся с Declarative Services.
- Выполнение RunnableRunner динамически перенастраивается при регистрации нового Runnable: невозможно, в какой-то момент я должен выполнить все Runnables в последовательности.
Любые советы по обеспечению того, чтобы какое-либо расширяемое обслуживание было «готовым» до его использования?
Спасибо за предложение листинга необходимых расширений в свойстве конфигурации. Проблема, которую я вижу при таком подходе, заключается в том, что клиенту требуется не только установка нового пакета, но и редактирование центрального файла конфигурации. Я бы предпочел, чтобы необходимая информация была предоставлена отдельными пакетами расширения децентрализованным способом. –
Как и Питер, также предлагает, хотите ли вы гарантировать, что все ваши расширения присутствуют, вам нужно указать какое-то условие для него. Это невозможно решить полностью. –