¿Qué es OSGi … y para que sirve?
Pues sí, otro acrónimo más en el mundo Java, no sé por qué te extrañas. Y como ha pasado con muchos otros de su época, véase SOAP, el acrónimo ha pasado a ser el nombre oficial, nombre que en sus orígenes era Open Services Gateway initiative. Bueno, vamos al turrón.
Un módulo es un componente autocontenido dentro de un sistema mayor. ¿Autocontenido?, sí, que no necesita de referencias externas para su existencia y funcionamiento.
Bien, detrás de esta definición de módulo tan abstracta se esconden dos de los principios fundamentales de la programación : Alta Cohesión y Bajo Acoplamiento.
Todo módulo debe tener una responsabilidad y funcionalidad perfectamente delimitada dentro de un sistema mayor en el que se encuentre integrado (alta cohesión). Y debe evitar cualquier dependencia con el resto de módulos para realizar la tarea que tiene asignada (bajo acoplamiento). Evidentemente, siempre existirá un determinado grado de acoplamiento, que debe estar, en la medida de lo posible, articulado mediante conceptos abstractos, lo que en Java vienen a ser las interfaces.
Se podría decir que dentro de la plataforma Java la analogía de módulo sería un fichero JAR. Sin embargo, si conocemos el proceso mediante el cual es cargado un fichero jar en la JVM, podemos advertir una serie de carencias que invitan a pensar que la modularización en Java es una mera ilusión.
Actualmente, por defecto, una JVM tiene un único class loader (system class loader que es cargado por el bootstrap class loader escrito en código nativo) responsable de cargar en la JVM cualquier clase que se encuentre dentro del classpath de ejecución de una aplicación Java. Cuando existe un fichero jar en el classpath, se carga cada una de las clases que contenga ese JAR. Todo se carga en un espacio común, ahí, al montón.
Seguramente alguna vez habréis cargado el mismo jar dos o más veces, si es de la misma versión no pasa nada pero si usas distintas versiones puede que tengas un problema. Si tienes dependencias con diferentes versiones de un mismo JAR, que sepas que se cargará la clase del jar que aparezca primero en el classpath. Esto implica que no podamos usar diferentes versiones de una misma clase, al menos, con la aproximación que Java tiene por defecto, tendríamos que crear nuestro propio classloader para cargar una versión distinta de la misma clase.
[Extender este punto]
La Alianza OSGi empezó a definir allá por el año 1999 (diez añitos ya) una especificación que permitiera la construcción de aplicaciones modulares en Java.

La especificación OSGi propone una arquitectura montada sobre una JVM que permita la instalación, actualización y eliminación de módulos. Cada módulo podrá publicar las clases que serán visibles por otros módulos de la máquina virtual y podrá consumir cualquier clase que haya sido publicada por otros módulos de la VM. Entre los módulos cliente y proveedor existe un registro central, en el que los proveedores registran los servicios que desean hacer públicos al resto de módulos y los clientes solicitan los servicios que desean consumir. Evidentemente un módulo puede ser, a la vez, cliente y proveedor. Este paradigma es similar a la solución definida en SOA, por ello se dice que:
Dentro de la especificación OSGi, un módulo tiene el nombre de bundle. Un bundle OSGi es un fichero JAR con un conjunto de metadatos que especifican las características de bundle. Estos metadatos deben de incluidos dentro del fichero MANIFEST.MF, por tanto :
Un ejemplo de MANIFEST.MF adaptado para ser utilizado dentro de un entorno OSGi puede ser el siguiente :
Manifest-Version: 1.0 Export-Package: org.apache.commons.logging;version="1.1.1",org.apache. commons.logging.impl;version="1.1.1";uses:="javax.servlet,org.apache. avalon.framework.logger,org.apache.commons.logging,org.apache.log,org .apache.log4j" Implementation-Title: Jakarta Commons Logging Implementation-Version: 1.1.1 Bundle-Classpath: . Built-By: dlg01 Specification-Vendor: Apache Software Foundation Bundle-Name: Apache Commons Logging Created-By: Apache Maven X-Compile-Source-JDK: 1.2 Implementation-Vendor: Apache Software Foundation Bundle-Vendor: SpringSource Implementation-Vendor-Id: org.apache Build-Jdk: 1.4.2_16 Bundle-Version: 1.1.1 Specification-Title: Jakarta Commons Logging Bundle-ManifestVersion: 2 Import-Package: javax.servlet;version="[2.1.0, 3.0.0)";resolution:=opt ional,org.apache.avalon.framework.logger;version="[4.1.3, 4.1.3]";res olution:=optional,org.apache.log;version="[1.0.1, 1.0.1]";resolution: =optional,org.apache.log4j;version="[1.2.15, 2.0.0)";resolution:=opti onal Bundle-SymbolicName: com.springsource.org.apache.commons.logging Specification-Version: 1.0 Extension-Name: org.apache.commons.logging Archiver-Version: Plexus Archiver X-Compile-Target-JDK: 1.2
El código anterior correponde al fichero MANIFEST.MF contenido en el JAR de Apache Commons Logging 1.1.1 descargado del repositorio OSGi de SpringSource.
De todas las cabeceras (headers) que componen el fichero vamos a explicar las más significativas:
- Bundle-SymbolicName : Única cabecera obligatoria y que debe identificar unívocamente dentro de la VM al bundle.
- Bundle-Version: Versión del bundle. La dupla (Bundle-SymbolycName,BundleVersion) permite referenciar una versión de un bundle.
- Export-Package : Lista de paquetes que el bundle publica para que puedan ser consumidos por otros bundles dentro de la misma VM.
- Import-Package : Lista de paquetes que el bundle necesita consumir y que por tanto deben ser exportados por otros bundles.
- Bundle-Classpath : Lista de rutas donde se encuentran las clases del bundle
Como habréis notado, todas las referencias a paquetes van acompañadas de un rango de versiones, no es obligatorio pero si recomendable. Por ejemplo, este bundle consume, de manera opcional, el paquete javax.servlet desde la versión 2.1.0 en adelante y menor a la 3.0.0. Esto permite a un bundle importar paquetes de varias versiones de un bundle, lo que puede ser necesario en ocasiones cuando tengamos dependencias con sistemas antiguos y que tengan dependencias con versiones antiguas mientras que la parte nueva del desarrollo esté vinculada a las versiones más modernas.
Otra ventaja es la posibilidad publicar únicamente lo que quiero que sea público a otros bundles sin necesidad de utilizar modificadores de ámbito a nivel de código como private, protected o package.
Por último os dejo con la definición que Craig Walls hace en su libro, Modular Java.
OSGi is a component framework specification that brings modularity to
the Java platform. OSGi enables the creation of highly cohesive, loosely
coupled modules that can be composed into larger applications. What’s
more, each module can be individually developed, tested, deployed,
updated, and managed with minimal or no impact to the other modules.Craig Walls,
Modular Java
Próximamente más.







