tutorial felix example español ejemplo compendium osgi

felix - ¿Cómo funciona la actualización del paquete OSGi?



osgi service (3)

Cuando se actualiza un paquete (por ejemplo, para corregir un error), ¿qué sucede con otros paquetes que están utilizando actualmente el que se está actualizando?

Digamos que hay dos paquetes de servicio y dao. Digamos que las clases en el paquete de servicios están usando clases en el paquete dao cuando emito un comando para actualizar la capa dao. ¿La clase en la capa de servicio que usa el código dao obtendrá una excepción?

Gracias por su response .

Quise decir actualizado con la misma versión.

hasta que se produce una actualización de paquete que incluye el paquete dependiente.

La operación de actualización del paquete es invocada por el usuario que actualiza el paquete, ¿verdad? Diga que cuando el usuario invoca la actualización para actualizar el paquete dao, una clase en el servicio de paquete invoca un método en una clase en la capa dao ... ¿qué sucede en este escenario?

Me ha resultado útil esta publicación de blog: http://solutionsfit.com/blog/2008/08/27/osgi-what-modularity-can-do-for-you-part-1/

Desde el post:

Si simplemente reemplazamos el paquete con un paquete que incluye la solución, el contenedor anulará el registro del paquete anterior y registrará el paquete nuevo. El proxy puede manejar la mezcla de referencias y reanudar la invocación del servicio. Esta interacción será casi instantánea. Sus clientes no se darán cuenta de lo que ha sucedido y usted acaba de ahorrar a su empresa una cantidad sustancial de dinero (¿escucho un bono?)

En esta publicación de blog, la llamada a authorizePayment () se puso en espera hasta que el paquete actualizado esté disponible. ¿Qué sucede si el control está dentro del método authorizePayment () cuando ocurre la actualización del paquete?


Cuando actualiza un paquete, utilizando el comando '' actualizar '' de OSGi, es muy probable que tenga otros paquetes dependientes que confían en él y ya están capturando un conjunto de clases cargadas de la versión anterior de este paquete. Una situación que normalmente se ajusta al problema que describió en su pregunta.

Para evitar posibles inconsistencias entre las diferentes versiones de las clases envueltas por este paquete, el contenedor OSGi decide ocultar temporalmente la nueva versión de las clases del paquete actualizado del mundo exterior. Puede pensar que es como mantener las clases actualizadas aisladas de los otros paquetes, momentáneamente .

El punto aquí es que el contenedor OSGi no puede simplemente comenzar a cargar clases desde la nueva versión del paquete de destino, ya que los paquetes dependientes terminarán viendo versiones antiguas de las clases que ya cargaron, combinadas con nuevas versiones de las mismas clases que se cargaron después de la actualización, lo que incorporaría una inconsistencia que daría como resultado un desorden incontrolable. Lo mismo ocurre con la desinstalación del paquete, el paquete se elimina de la lista de paquetes instalados, pero no se elimina de la memoria. Se mantendrá alrededor para que los paquetes dependientes puedan continuar cargando clases desde él.

Por lo tanto, puede pensar que el comando ''actualizar'', como introducción de una nueva versión del mismo paquete, se entregará solo a los paquetes dependientes que aún están por venir, que aún no están disponibles al momento de la actualización. Si bien la versión anterior, que existía antes de la actualización, permanece en la memoria para asegurar la compatibilidad con versiones anteriores y evitar cualquier posible interrupción de los paquetes existentes que ya han comenzado a depender del paquete actualizado.

Tenga en cuenta que las versiones anteriores solo se guardan en la memoria, lo que significa que un reinicio en el servidor resultará en la erradicación de todas estas versiones antiguas y traerá la última versión a la tabla. Esto tiene mucho sentido, porque no habrá necesidad de compatibilidad con versiones anteriores, simplemente porque todos los paquetes se están iniciando al mismo tiempo.

Lo que sucede a continuación es que debe invocar explícitamente el comando '' actualizar '' en paquetes específicos, aquellos que dependen del paquete actualizado, o en su lugar, puede elegir ejecutar el comando ''actualizar'' sin especificar un paquete específico, lo que significa que todos los paquetes serán refrescados a ciegas. El comando ''actualizar'' obliga a reconstruir el árbol de dependencias de los paquetes de destino y obliga a sus cargadores de clases a comenzar a cargar sus clases requeridas desde cero.

Solo entonces los paquetes dependientes comenzarán a ver los cambios que ha realizado en el código de las clases que viven en el paquete que se ha actualizado.

La regla es que

Los paquetes resueltos existentes que ya importan una versión anterior de una clase no se volverán a cablear automáticamente al nuevo paquete a menos que se actualicen.


Cuando se actualiza un paquete, se instala una nueva revisión (los bits del paquete). Si otro paquete está conectado a la revisión anterior del paquete actualizado, es decir, otro paquete importado algún paquete exportado por la revisión anterior u otro paquete requirió el paquete en la revisión anterior, entonces el marco OSGi conservará la revisión previa del paquete actualizado. paquete para atender futuras solicitudes de carga de clase desde el paquete dependiente hasta que se produzca una actualización del paquete que incluya el paquete dependiente.

El propósito de esto es minimizar o retrasar la perturbación de los paquetes dependientes cuando se actualiza una dependencia. Un agente de administración puede querer actualizar varios paquetes y, al final, hacer una actualización de paquetes para "modernizar" las dependencias. Una vez que se realiza la actualización del paquete, no hay cables para la revisión anterior del paquete actualizado y el marco OSGi ahora es libre de descartar la revisión anterior.

Así que en su ejemplo, generalmente no habrá ninguna excepción. Pero, por supuesto, depende de lo que realmente esté haciendo el código en cuestión y de cómo se escriben sus manifiestos.


Los paquetes tienen 2 tipos de dependencias:

  • Servicios, y
  • Conexiones entre cargadores de clases, codificadas por los nombres de los paquetes. Esas conexiones se llaman cables.

Los servicios son fáciles de retirar porque eso es intrínseco a su diseño. Los cables son más difíciles porque están intrincadamente tejidos en tus objetos y esos objetos no son conscientes de la dinámica. Así que cuando instalas un paquete nuevo, los paquetes antiguos se quedan como están, tus objetos no se actualizan y el paquete actualizado aún proporciona sus cables como un zombi.

Cuando llama a refreshPackages, el marco analiza esas dependencias y encuentra los paquetes que se refieren a esos zombies. Cada zombie es detenido. El contrato para un paquete es que se debe limpiar. Ayudamos al paquete haciendo una gran cantidad de limpieza por usted, pero algunas cosas son muy malas, por ejemplo, almacenar referencias en estática de otros paquetes u olvidar detener los subprocesos que se iniciaron. Otros paquetes que dependen de otras formas de esos paquetes son notificados de la detención del paquete para que también puedan limpiar cualquier referencia. Una vez que se detienen los paquetes, éstos no se resuelven y luego se resuelven de nuevo contra los paquetes nuevos.

Para paquetes de OSGi reales, la limpieza es natural y no es realmente visible en su código (como debería ser). Está bien soportado por las herramientas como servicios declarativos, iPOJO, administrador de dependencias, Spring, Blueprint, etc. La magia se centra en el modelo de servicios y no en los hacks de carga de clase dong.

¿Por qué no estamos refrescando automáticamente? Bueno, una vez lo hicimos pero refrescante es disruptivo. En muchos casos es necesario actualizar varios paquetes. Tener esta interrupción después de cada actualización sería innecesariamente doloroso. Es decir, después de una instalación o actualización, SIEMPRE debería hacer una actualización, pero puede poner entre paréntesis varias instalaciones / actualizaciones.