Introducción
Uno de los “problemas/features” cuando uno usa Maven/Ivy/Grape o sistemas similares para gestionar sus dependencias es que independientemente de la versión, las librerías acaban teniendo un nombre común. Es decir, que la librería org.hibernate:hibernate:3.2.6.ga acaba llamandose hibernate.jar, igual que si fuera la 3.3.0.SP1 o cualquier otra versión. Esta característica ayuda a la hora de reemplazar una versión con otra, pero dificulta averiguar de un vistazo que versiones de librería estamos utilizando.
En caso de que nosotros hagamos una librería y se use a través de uno de estos sistemas, nuestros usuarios tendrán el mismo problema para averiguar en el sistema final qué versión está desplegada. Como somos unos “grandes” programadores, queremos facilitar a nuestros usuarios el averiguar está información, pero como somos unos programadores
Implementación
Paso 1:
Lo primero que tenemos que hacer es almacenar el número de versión de forma automática en algún sitio. Un buen sitio para hacerlo es en el fichero Manifest de nuestro .jar, y para hacerlo de forma automática podemos utilizar el plugin de Maven org.codehaus.mojo.buildnumber-maven-plugin. La documentación que tiene no es demasiado extensa, pero investigando un poco podemos averiguar cómo usarlo. En mi caso, dado que utilizo Mercurial como sistema de versiones y el numero de versión que utiliza no es muy significativo (no es un número correlativo) así que lo he sustituido por una marca de tiempo que me da una indicación más fiable. Si usas algo como Subversion, entonces quizá la configuración estándar del plugin ya te sirva Dado que el plugin no se encuentra en el repositorio central de Maven, tenemos que añadir un repositorio de plugins para encontrarlo, de la siguiente forma:
codehaus-snapshot Cohehaus snapshot repository https://nexus.codehaus.org/content/groups/snapshots-group true
Una vez hecho esto, configuramos el plugin para que nos defina unas variables con la información que queremos, así:
org.codehaus.mojo buildnumber-maven-plugin 1.0-beta-5-SNAPSHOT validate create true true {0,date,dd/MM/yyyy HH:mm:ss} - timestamp
Con esto le decimos que nos añada el timestamp a la variable buildNumber, que es donde el plugin pone su información.
Por último, configuramos el plugin org.apache.maven.plugins.maven-jar-plugin para que use esa información para añadir una nueva entrada en el Manifest de nuestro jar. De la siguiente forma:
org.apache.maven.plugins maven-jar-plugin 2.3.1 false ${version}-${buildNumber} my.package.MainApp
Una vez hecho esto, si ejecutamos mvn package, por ejemplo, para generar nuestro fichero ,jar y miramos el fichero MANIFEST.MF dentro del directorio META-INF, deberíamos ver algo tal que así:
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: usuario Build-Jdk: 1.6.0_21 Main-Class: my.package.MainApp MyLibrary-version: 0.1-SNAPSHOT-25/06/2011 13:33:01
Paso 2:
Bien, ya tenemos almacenada la versión en el .jar. ¿Ahora que hacemos para facilitar que el usuario pueda ver esa información sin tener que abrir el .jar y mirar el manifest? Muy sencillo: la clase my.package.MainApp que es la principal de nuestra aplicación tiene que mostrar esa versión. En mi caso, la librería es una utilidad que no se lanza en linea de comandos, se usa añadiéndola al classpath, así que mi clase MainApp simplemente muestra la versión de la librería.
¿Y como hacemos para leer el manifest del mismo fichero del cual nos estamos ejecutando? Pues averiguando donde se encuentra el .jar en tiempo de ejecución y accediendo a él para leer el fichero manifest. Podemos hacerlo así (código simplificado sin gestión de errores):
String jarFileURL = MainApp.class.getProtectionDomain().getCodeSource().getLocation().toString(); int pos = jarFileURL.indexOf("!"); if(pos!=-1) { jarFileURL = jarFileURL.substring(0,pos); } if(!jarFileURL.startsWith("jar:")) { jarFileURL = "jar:" + jarFileURL; } URL manifestUrl = new URL(jarFileURL + "!/META-INF/MANIFEST.MF"); Manifest manifest = new Manifest(manifestUrl.openStream()); return manifest.getMainAttributes().getValue(“MyLibrary-version”);
Y así podemos hacer que al ejecutar java -jar milibreria.jar nos devuelva la versión de la librería, o si lo ponemos en un método público, podemos usar este número para mostrarlo en las aplicaciones que usen la librería y así puedan saber que versión están utilizando, comprobar si existen nuevas versiones etc.
Espero que os sirva, al menos a mi me ha servido, y que vuestros usuarios estén más contentos :).
Happy coding! EJ
No hay comentarios:
Publicar un comentario