Mirando OSGi

osgi allianceOSGI es una de esas cosas de las que quería enterarme de qué iba y aprovechando el manual de OSGi de Roberto Montero publicado en javahispano, me he puesto a ello.

El manual, para alguien como yo que tiene ciertos conocimientos de java y no le suenan a chino cosas como fichero de manifiesto, classloader o maven, pero que no tiene ni puñetera idea de qué es OSGi, está muy bien. Da una explicación desde el principio y mostrando un ejemplo "Hola Mundo" en diversas plataformas y con distintas herramientas (Equinox, Apache Félix, Eclipse, Pax Constructor, etc). Al final me queda más o menos claro qué es OSGi y sólo queda hacerme mis propios ejemplos y pruebas.

La idea básica de OSGi es que es una forma de desarrollar aplicaciones java a base de hacer módulos más o menos independientes, pero que pueden colaborar entre ellos. Estos módulos (llamados bundles) no son más que jars con algunas clases especiales propias de OSGi y un fichero de manifiesto con campos especiales, que entiende OSGi. Los bundles pueden colaborar entre ellos, indicando qué paquetes java exportan a otros módulos y qué paquetes java de otros módulos necesitan. Una plataforma que implemente OSGi (Equinox o Apache Félix entre otras) es capaz de cargar, arrancar o parar estos módulos en tiempo de ejecución, sin necesidad de tirar la aplicación y volver a arrancarla. También es capaz de saber qué módulos dependen de cuales para pararlos si les faltan dependencias o arrancarlos sólo cuando todas sus dependencias están cargadas.

Sin embargo hay un problema que tengo de hace mucho y que veo que OSGi no me va a solucionar. Cuando hay dos módulos (jars) que se quiere que colaboren, al final no queda más remedio que uno de ellos vea (necesite) al otro para compilar, ya que si un módulo usa otro, debe ver al menos alguna interface o tipo de dato. Esto hace que los módulos no sean realmente independientes y no puedas aprovechar un módulo para otro proyecto. Si en otro proyecto quiero llevarme el móudlo A y este tira de una interface de B, pues me tengo que llevar B también y éste, desgraciadamente, en una de sus clases que no necesito para nada, tira de una interface del módulo C y así sucesivamente. Para proyectos grandes con muchos programadores (expertos y novatos), lo normal es que todos los módulos acaben dependiendo de todos e incluso empiece a haber dependencias cruzadas. Sí, ya sé que "sólo" es cuestión de pensar antes que módulos debe haber, cómo dependen unos de otros y "sólo" hay que conseguir que todos los programadores respeten esa arquitectura.

Una posible solución, que había descartado, para este problema es que cada módulo fuera en realidad dos módulos. Uno pequeño, con sólo las interfaces y clase de datos (beans) que es lo que dependerían los demás módulos. Y otro módulo más grande con todo el resto del código. Lo descarté porque en un proyecto grande con 30 o 40 módulos, se nos duplica el número de módulos y de jars.

Sin embargo, en los ejemplos OSGi que he visto, parece que hace eso mismo. Si crea un módulo que es un servicio que van a ver otros módulos, crea dos módulos: uno con la interface del servicio y los bean de datos, el otro con la implementación. Los módulos que usen servicios de éste, sólo dependen del módulo pequeño con la interface.

En fin, a jugar un poco con OGSi y a repensar esto de partir los módulos en dos submódulos: lo visible al exterior y la implementación concreta.

Esta entrada ha sido publicada en diseño, Herramientas y etiquetada como , , . Guarda el enlace permanente.

5 respuestas a Mirando OSGi

  1. sapito169 dijo:

    digamos que tienes que hacer una aplicación cliente servidor en java igual estas obligado a trabajar en modulos incluso si no utilizas osgi asi que es lo mismo adamas tiene mas ventajas que desventajas

  2. jneira dijo:

    «Whereas typical factories will be implemented using some form of class name acquired via a properties file and a subsequent Class.forName(), OSGi maintains a ‘service registry’ – in essence, a map containing a list of class names and services. So, instead of using class.forName(«com.example.JDBCDriver») to acquire a JDBC driver, an OSGi system could use context.getService(getServiceReference(«java.sql.Driver»)) instead.»

    No esta mal aunque no sea «magico». La cuestion es que mientras tengas un bundle que proporcione una implementacion concreta puedes is cambiandolos, recargarlos etc. Con el nivel suficiente de abstraccion (si es posible) puede ser bastante potente. Por ejemplo en el caso de sql cambiar un bundle por otro te permite cambiar de un tipo de servidor de base de datos a otro al vuelo. La cita es de http://www.infoq.com/articles/modular-java-dynamic-modularity de Noviembre de 2009 pero sigue estando bien.

    Como me dijeron hace tiempo en este foro: «ah, eso del osgi es eso del eclipse….» 😛

  3. Pingback: de la red – 7/05/2010 « Tecnologías y su contexto

  4. Lek dijo:

    Hombre, en cierta manera de las dependencias en cascada no te vas a librar de ninguna manera por arte de magia… siempre vas a necesitar que la gente se ponga las pilas y defina correctamente todo el árbol de dependencias y abstraiga las implementaciones lo más posible

  5. Chuidiang dijo:

    Sí, eso lo tengo claro. Lo que me da «pereza» es lo que comento. Si un módulo A tira de un módulo B y no quiero cargar con todo el jar de B, implementaciones y demás incluidas, tengo que hacer un tercer módulo IfzB con sólo interfaces y tipos de datos, de forma que B implementa IfzB y A usa IfzB. Demasiada complejidad.

    Al final, como siempre, supongo que hay que llegar a un compromiso entre lo cambiable/mejorable que vaya a ser B y la simplicidad.

    Se bueno.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.