Generar un zip con aplicacion OSGI

De ChuWiki
Saltar a: navegación, buscar

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

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

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 fichero config.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

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

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

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

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.