2009-10-14 4 views
9

Я создал пакет OSGi с открытым (декларативным) сервисом. Если я, когда вызвана активация, заметьте, что что-то не так, что я не могу предоставить услугу, мне нужно предотвратить ее. На данный момент функция активации выглядит так:Каков правильный способ отключения службы OSGi при запуске службы?

public void activate(ComponentContext context, Map<String, Object> properties) { 
    pid = (String) properties.get(Constants.SERVICE_PID); 
    try { 
     ... 
    } 
    catch(Exception e) { 
     context.disableComponent(pid); 
    } 
} 

Другой альтернативой является просто обернуть/распространяет исключение (или бросить новый, в зависимости), как это:

public void activate(ComponentContext context, Map<String, Object> properties) { 
    try { 
     ... 
    } 
    catch(Exception e) { 
     throw new ComponentException("Some reason"); 
    } 
} 

Я не могу найти правильное поведение, указанное в разделе декларативных услуг в OSGi Service Platform Service Compendium, но мне может быть что-то не хватает

ответ

8

Хм, для меня кажется логичным, что при возникновении ошибки следует исключать исключение. В основном, то, что вы делаете тогда, имитирует поведение BundleActivator в методе start. Пакет входит в состояние ACTIVE, когда метод start возвращается без исключения (иначе он остается в RESOLVED). Я нашел несколько подходящий абзац в спецификации DS (я выделил интересную часть):

Экземпляр компонента должен завершить активацию до его деактивации. После того, как конфигурация компонента деактивирована или не активируется из-за исключения, SCR должен отпереть все связанные службы компонента и отказаться от всех ссылок на экземпляр компонента, связанный с активацией.

Раздел 112.5.6 с.320 в OSGi 4.2 cmpn spec

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

public void activate(ComponentContext context, Map<String, Object> properties) { 
    try { 
     ... 
    } catch(Exception e) { 
     context.disableComponent((String) properties.get(Constants.SERVICE_PID)); 
     // not sure if a CE is best here... Maybe just rethrow the original one 
     throw new ComponentException("Some reason"); 
    } 
} 

Cheers, Мирко

0

Компонент отключив себя очень вряд ли будет соответствующий дизайн OSGI. Что позволит компоненту улучшить ситуацию? Состояние с включенным/отключенным состоянием будет отличаться от логического уровня, чем активировано/деактивировано.

Правильно разработанный код OSGI должен иметь дело с кодом, который генерирует исключение ComponentException (или другое исключение) при сбое активации. Предполагая, что компонент зарегистрирует службу, ссылка на службу будет доступна, но попытка получить услугу вернет значение null. DS правильно справится со ссылками на эту услугу, и любой код, который непосредственно пытается получить услугу из ссылки на службу, должен иметь дело с возможностью того, что услуга фактически недоступна.

Однако это может сбить с толку. В Felix DS я реализовал расширение, посредством которого компоненты могут изменять свои собственные свойства сервиса, хотя это не было принято в спецификации. Используя это расширение, компонент может добавить свойство службы, такое как active = true, когда активация или модификация преуспевают и удаляются, когда модификация завершается неудачно или деактивируется. Клиенты службы могут фильтровать это свойство службы, например. (Активный = истина).