2009-10-14 11 views
9

He creado un paquete OSGi con un servicio expuesto (declarativo). Si yo, cuando se llama a activar, noto que algo anda mal y no puedo prestar el servicio, necesito evitar que se exponga. Por el momento la función de activación se ve así:¿Cuál es la forma correcta de deshabilitar un servicio OSGi al inicio del servicio?

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

Otra alternativa es simplemente envuelva/propagar la excepción (o lanzar uno nuevo, dependiendo) de esta manera:

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

no puedo encontrar el comportamiento correcto especificado en la sección sobre servicios declarativos en el OSGi Service Platform Service Compendium, pero podría faltar algo

Respuesta

8

Hmm, para mí parece lógico que se genere una excepción si se produce un error. Básicamente, lo que estás haciendo es imitar el comportamiento de un BundleActivator en el método de inicio. El paquete entra en el estado ACTIVO cuando el método de inicio regresa sin una excepción (de lo contrario, permanece en RESUELTO). Encontré un párrafo algo apropiado en la especificación DS (destaqué la parte interesante):

Una instancia del componente debe completar la activación antes de poder desactivarla. Una vez que la configuración del componente está desactivada o no se activa debido a una excepción, SCR debe desvincular todos los servicios enlazados del componente y descartar todas las referencias a la instancia del componente asociada con la activación.

Sección 112.5.6 p.320 en el OSGi 4.2 cmpn spec

estoy de acuerdo que esto no es claro como el cristal, así que si quieres estar en el lado seguro (mejor prevenir que curar), que recomendaría a hacer la combinación (permitido por la especificación).

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 incapacitante en sí es muy poco probable que sea un diseño OSGI apropiado. ¿Qué habilitará el componente cuando mejore la situación? El estado habilitado/deshabilitado tiene la intención de ser un nivel lógico diferente que el activado/desactivado.

El código OSGI correctamente diseñado debe tratar correctamente con el código que arroja una excepción ComponentException (u otra excepción) cuando falla la activación. Suponiendo que el componente registra un servicio, la referencia de servicio estará disponible pero intentar obtener el servicio devolverá nulo. DS tratará correctamente las referencias al servicio, y cualquier código que intente directamente obtener el servicio de la referencia del servicio debe tratar adecuadamente la posibilidad de que el servicio no esté realmente disponible.

Sin embargo, esto puede ser confuso. En Felix DS implementé una extensión mediante la cual los componentes pueden cambiar sus propias propiedades de servicio, aunque esto no ha sido aceptado en la especificación. Con esta extensión, un componente puede agregar una propiedad de servicio, como active = true, cuando la activación o modificación se realiza correctamente y eliminarla cuando la modificación falla o cuando se desactiva. Los clientes del servicio pueden filtrar en esta propiedad del servicio, p. (activo = verdadero).

Cuestiones relacionadas