2010-12-02 17 views
21

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?¿Cómo funciona la actualización del paquete OSGi?

Diga que hay dos paquetes de servicio y dao. Supongamos que las clases en el paquete de servicios utilizan clases en paquete dao cuando emite el comando para actualizar la capa de dao. ¿La clase en la capa de servicio que usa el código dao obtiene una excepción?


Gracias por su response.

Quería decir actualizado con la misma versión.

hasta que se produce una renovación del paquete que incluye el paquete dependiente.

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

me encontré con este post del blog útil: http://solutionsfit.com/blog/2008/08/27/osgi-what-modularity-can-do-for-you-part-1/

Desde el puesto de:

Si simplemente sustituimos el paquete con un paquete que incluye la revisión, el contenedor se anulará el registro del antiguo paquete y registrar el nuevo paquete. El proxy puede manejar la mezcla de referencias y reanudar la invocación del servicio. Esta interacción será casi instantánea. Sus clientes serán completamente ajenos a lo que sucedió y usted acaba de ahorrarle a su empresa una cantidad sustancial de dinero (¿escucho una bonificación?).

En esta publicación de blog, la llamada a authorizePayment() se suspendió 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?

Respuesta

5

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 importó algún paquete exportado por la revisión anterior u otro paquete requirió el paquete en la revisión anterior, entonces el marco OSGi retendrá la revisión previa de la actualización paquete para atender las futuras solicitudes de carga de clase del 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 paquetes dependientes cuando se actualiza una dependencia. Es posible que un agente de administración desee actualizar varios paquetes y, al final, actualice los paquetes para "modernizar" las dependencias. Una vez que se realiza la renovación del paquete, no hay cables para la revisión previa del paquete actualizado y el marco OSGi ahora es libre de descartar la revisión anterior.

Por lo tanto, en su ejemplo, generalmente no se producirá ninguna excepción. Pero, por supuesto, depende de lo que realmente está haciendo el código en cuestión y cómo están escritos los manifiestos del paquete.

17

paquetes tienen 2 tipos de dependencias:

  • Servicios y
  • Las conexiones entre cargadores de clases, cerrado por el paquete nombres. 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 entretejidos en sus objetos y esos objetos no son conscientes de la dinámica. Por lo tanto, cuando instala un paquete nuevo, los paquetes anteriores permanecen como están, sus objetos no se actualizan y el paquete actualizado aún proporciona sus cables como un zombi.

Cuando llama a refreshPackages, el framework examina esas dependencias y encuentra los paquetes que hacen referencia a esos zombies. Cada zombie se detiene. El contrato para un paquete es que debería limpiarse. Ayudamos al paquete haciendo una gran cantidad de tareas de limpieza, pero algunas cosas son muy malas, p. almacenar referencias en estática de otros paquetes u olvidarse de detener los hilos que se iniciaron. Otros paquetes que dependen de otros modos en esos paquetes son notificados de la detención del paquete para que también puedan limpiar cualquier referencia. Después de detener los paquetes, los paquetes no se resuelven y luego se resuelven nuevamente con los nuevos paquetes.

Para los paquetes 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 los servicios y no en los ataques de carga de la clase dong.

¿Por qué no estamos actualizando automáticamente? Bueno, una vez lo hicimos, pero refrescante es perjudicial. En muchos casos, necesita actualizar múltiples paquetes. Tener esta interrupción después de cada actualización sería innecesario y doloroso. Es decir, después de una instalación o actualización, SIEMPRE debe hacer una actualización, pero puede agregar varias instalaciones/actualizaciones.

6

Al actualizar un paquete, usando la OSGi 'actualización' comandos, es más probable que tengan otros lotes dependientes que están confiando en ella y ya la captura de un conjunto de clases cargadas de la versión anterior de este haz. Una situación que normalmente se ajusta al problema que describió en su pregunta.

Para evitar posibles incoherencias entre las diferentes versiones de las clases contenidas en 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 objetivo, porque los paquetes dependientes terminarían viendo versiones antiguas de las clases que ya cargaron, mezcladas con nuevas versiones de las mismas clases que se cargaron después de la actualización, que incorporarían una incoherencia que daría lugar a un desastre incontrolable. Lo mismo ocurre con el paquete Desinstalar, 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 seguir cargando clases desde allí.

Así se puede considerar que el comando 'actualización', como la introducción de una nueva versión del mismo paquete, para ser única suministra a lotes dependientes que están por venir, -que todavía no existe en el momento de la actualización-.Mientras que la versión anterior, que existía antes de la actualización, sigue siendo en la memoria para garantizar la compatibilidad con versiones anteriores y evitar cualquier posible interrupción en 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 dará como resultado la eliminación de todas estas versiones antiguas y la última versión en la tabla. Esto tiene mucho sentido, porque no habrá necesidad de compatibilidad con versiones anteriores, simplemente porque todos los paquetes están empezando al mismo tiempo ..

Lo que sucede después, es que usted tiene que invocar explícitamente el 'actualización 'comando en paquetes específicos, -los 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 se actualizarán a ciegas. El comando 'actualizar' fuerza la reconstrucción del á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

existentes paquetes resueltos ya la importación de una versión anterior de una clase no serán rewired automáticamente al nuevo paquete a menos que sean renovados.

Cuestiones relacionadas