Generar un zip con aplicacion OSGI
En este tutorial, usando Maven vamos a crear un zip en el que vaya todo lo necesario para arrancar Apache Felix con nuestros módulos OSGI (bundles). El ejemplo completo lo tienes en OSGIAssembly
Elección de la implementación de OSGI[editar]
Sin atender a qué implementación de OSGI (Apache Felix, Equinox, ...) es mejor, vamos a elegir una u otra en función de lo fácil que sea descargársela del repositorio central de maven. Sin lugar a dudas, en el momento de hacer este tutorial, Apache Felix está perfectamente subido al repositorio central, mientras que la distribución de Equinox deja bastante que desear ... no se encuentran los jar fácilmente por su manía de ponerles número de versión estrambóticos como org.eclipse.osgi_3.10.101.v20150820-1432.jar, o bien otros que se encuentran y simplemente están vacíos por dentro, como org.eclipse.equinox.ds
Así que vamos con Apache Felix, cuyos jar están subidos correctamente a maven, con números de versión normales y fácilmente encontrables.
Qué queremos conseguir[editar]
Lo que pretendemos es que al desempaquetar nuestro zip, generado con maven, nos quede la siguiente estructura de directorios/ficheros
OSGIAssembly-0.0.1 +- bundle | +- org.apache.felix.scr-2.0.2.jar | +- OSGIFactory-0.0.1.jar +- conf | +- config.properties +- org.apache.felix.main-5.4.0.jar +- run.bat
es decir:
- un subdirectorio
bundle
con todos los bundles que queramos para nuestra aplicación, tanto nuestros como descargados del repositorio central de maven - un subdirectorio
conf
con el ficheroconfig.properties
que contendrá la configuración de Apache Felix. - El ejecutable de Apache Felix
org.apache.felix.main-5.4.0.jar
- Un script de arranque que no nos obligue a recordar el comando exacto de arranque de Apache Felix.
Nuestro proyecto Maven[editar]
Nuestro proyecto maven sólo va a generar el zip, cogiendo los jar/bundles que necesite de Apache Felix del respositorio central de maven, y nuestros propios jar/bundles de nuestro repositorio local, procedentes de algún otro proyecto Maven y osgi que hayamos hecho previamente. No tendremos en principio código en este proyecto ni ninguna otra cosa, salvo el pom.xml y algunos ficheros que van a ir en el zip.
Para generar el zip, usaremos el plugin maven-assembly-plugin. En el pom.xml sólo debemos poner el plugin correspondiente
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptor>src/assembly/dep.xml</descriptor>
</configuration>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Simplemente hemos añadido el plugin, en su última versión disponible en el momento de hacer este tutorial. Indicamos que el fichero que indique qué cosas lleva el zip está en src/assembly/dep.xml
. Y finalmente indicamos que de este plugin debe ejecutarse el comando single
cuando ejecutemos mvn package
. Este comando single
es el que generará el zip.
Fichero de configuración y script de arranque de Apache Felix[editar]
Apache Felix, cuando se arranca, busca un fichero de configuración en conf/config.properties
. Para facilitar el arranque también necesitamos un pequeño script (un bat en el caso de windows run.bat
) con el comando de arranque. Metemos ambas cosas en el directorio src/main/config
de nuestro proyecto maven, con su estructura final, tal que así
src/main/config +- conf | +- config.properties +- run.bat
De esta forma, nos bastará con meter en el zip el contenido tal cual del directorio src/main/config
y quedará correctamente colocado.
El fichero run.bat
contiene algo como
java -jar org.apache.felix.main-5.4.0.jar
donde org.apache.felix.main-5.4.0.jar
es el jar de arranque de Apache Felix, que maven se bajará por nosotros más adelante.
Y el fichero config.properties
puede tener cualquier configuración que queramos darle a Apache Felix. Esta sería la mínima
felix.auto.deploy.action=install,start
que le indica a Apache Felix que instale y arranque todos los bundles que encuentre en el directorio de bundles. Por defecto, este directorio se llama bundle
.
Dependencias[editar]
Los único jar que necesitamos son el de arranque de Apache Felix, es decir, org.apache.felix.main-5.4.0.jar
. Adicionalmente, podemos añadir otros bundles que nos vengan bien, como por ejemplo org.apache.felix.scr-2.0.2.jar
, o los nuestros propios, como OSGIFactory-0.0.1.jar
(Este es mio, solo como ejemplo por traer algo, pon los tuyos propios). Con todo esto, las dependencias en maven quedarían
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.scr</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
<version>5.4.0</version>
</dependency>
<dependency>
<groupId>com.chuidiang.examples</groupId>
<artifactId>OSGIFactory</artifactId>
<version>0.0.1</version>
<scope>runtime</scope>
</dependency>
</dependencies>
Poco que decir sobre las dependencias. Se les pone scope runtime porque no las necesitamos realmente para compilar. Todas ellas son bundles de OSGI.
Fichero dep.xml[editar]
El fichero src/assembly/dep.xml
contiene los detalles de cómo queremos nuestro jar. Veamos las partes interesantes
<fileSets>
<fileSet>
<directory>src/main/config</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
Esta parte dice que se meta el contenido del directorio src/main/config
dentro el raíz de nuestro zip. Con esto metemos en el zip el fichero run.bat
y el fichero de configuración conf/config.properties
<dependencySet>
<outputDirectory>/bundle</outputDirectory>
<unpack>false</unpack>
<scope>runtime</scope>
<useTransitiveDependencies>false</useTransitiveDependencies>
<excludes>
<exclude>com.chuidiang.examples:OSGIAssembly</exclude>
<exclude>org.apache.felix:org.apache.felix.main</exclude>
</excludes>
</dependencySet>
Con esto se meten las dependencias dentro del zip, en el subdirectorio bundle
. Indicamos que no queremos que las desempaquete, es decir, que queremos dentro del zip el jar tal cual, sin desempaquetar. Indicamos que queremos sólo las dependencias runtime
, que es el scope
que habíamos puesto en el pom.xml
. Excluimos las dependencias transitivas, es decir, excluimos las dependencias de las que dependen nuestros jar. El motivo es que en OSGI, un bundle suele llevar dentro del jar sus propias dependencias, y no las necesitamos por tanto, también en nuestro zip.
Y finalmente, excluimos el ejecutable de Apache Felix y el jar que generará nuestro propio proyecto maven (que en este caso tiene el nombre OSGIAssembly) y que estará vacío (no tenemos ninguna clase).
Ahora ponemos "algo" para que el ejecutable de Apache Felix quede en el raíz del zip
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>false</unpack>
<scope>runtime</scope>
<useTransitiveDependencies>false</useTransitiveDependencies>
<includes>
<include>org.apache.felix:org.apache.felix.main</include>
</includes>
</dependencySet>
Es básicamente lo mimo de antes, pero esta vez el directorio de salida (dentro del zip), será el raíz /
y que en vez de excluir dos jar concretos, esta vez sólo queremos que incluya uno concreto, el del ejecutable de Apache Felix.
Y con esto está todo listo. Una ejecución de
mvn package
dejará en el directorio target un zip OSGIAssembly-0.0.1-dep.zip
que podremos llevarnos y desempaquetar en cualquier sitio. Bastará un doble click sobre run.bat
para que nuestra aplicación hecha a base de bundles OSGI arranque.