2009-10-14 7 views
9

Ho creato un bundle OSGi con un servizio esposto (dichiarativo). Se io, quando viene chiamato l'attivazione, noti che qualcosa non funziona in modo tale da non poter fornire il servizio, ho bisogno di impedirne l'esposizione. Al momento la funzione di attivazione si presenta in questo modo:Qual è il modo corretto di disabilitare un servizio OSGi all'avvio del servizio?

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

Un'altra alternativa è quella di avvolgere solo/propagare l'eccezione (o lanciare uno nuovo, a seconda) in questo modo:

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

non riesco a trovare il comportamento corretto specificato nella sezione sui servizi dichiarativi nello OSGi Service Platform Service Compendium, ma potrei mancare qualcosa

risposta

8

Hmm, per me sembra logico che un'eccezione debba essere generata se si verifica un errore. Fondamentalmente, quello che stai facendo è imitare il comportamento di un BundleActivator nel metodo di avvio. Il bundle entra nello stato ACTIVE quando il metodo di avvio ritorna senza un'eccezione (altrimenti rimane in RISOLTO). Ho trovato un paragrafo piuttosto adeguato nelle specifiche DS (ho evidenziato la parte interessante):

Un'istanza di componente deve completare l'attivazione prima che possa essere disattivata. Una volta disattivata la configurazione del componente o l'attivazione di a causa di un'eccezione, SCR deve separare tutti i servizi associati del componente e scartare tutti i riferimenti all'istanza del componente associata all'attivazione.

Sezione 112.5.6 P.320 nel OSGi 4.2 cmpn spec

sono d'accordo che questo non è cristallino, quindi se si vuole essere al sicuro (meglio prevenire che curare), mi sento di raccomandare a fai la combinazione (permesso dalla specifica).

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, Mirko

0

Un componente invalidante in sé è molto improbabile che sia un disegno OSGI appropriata. Cosa abiliterà il componente quando la situazione migliorerà? Lo stato abilitato/disabilitato deve essere un livello logico diverso da attivato/disattivato.

Il codice OSGI correttamente progettato deve gestire correttamente il codice che genera una ComponentException (o altra eccezione) quando l'attivazione non riesce. Supponendo che il componente registri un servizio, il riferimento al servizio sarà disponibile ma il tentativo di ottenere il servizio restituirà null. DS gestirà correttamente i riferimenti al servizio e qualsiasi codice che tenta direttamente di ottenere il servizio dal riferimento al servizio deve trattare correttamente con la possibilità che il servizio non sia effettivamente disponibile.

Tuttavia, questo può essere fonte di confusione. In Felix DS ho implementato un'estensione per cui i componenti possono modificare le proprie proprietà del servizio, sebbene questo non sia stato accettato nelle specifiche. Usando questa estensione, un componente può aggiungere una proprietà di servizio come active = true quando l'attivazione o la modifica riesce e rimuoverlo quando la modifica fallisce o alla disattivazione. I client del servizio possono filtrare su questa proprietà del servizio, ad es. (Attivo = true).