Maven Assembly Plugin: empaquetando aplicaciones con Maven para la ejecución de procesos batch.
0. Índice de contenidos.
- 1. Introducción.
- 2. Entorno.
- 3. Configuración del módulo batch.
- 4. El resultado del empaquetado.
- 5. Los scripts de los procesos batch.
- 6. Conclusiones.
1. Introducción
Ya hemos escrito en adictos sobre Empaquetamiento de
aplicaciones de escritorio (standalone) con Maven y, en este tutorial, vamos a hablar sobre el mismo plugin pero orientado al empaquetamiento de un módulo de
nuestra aplicación para la ejecución de procesos batch, o la ejecución de procesos puntuales, de migración de datos, que requieren tener montado todo el entorno de la capa
de servicios de nuestra aplicación.
Estamos hablando de aplicaciones JEE, lo suficientemente bien modularizadas y la necesidad consiste en ejecutar una aplicación standalone, que tenga accesibles
los mismos servicios que tendría el módulo web.
Para dar soporte a esos procesos batch o de migración, vamos a crear un módulo específico dentro de nuestra estructura de aplicación, al que llamaremos app-batch,
y que, como el resto de módulos, dependerá de un módulo parent.
2. Entorno.
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil Asus G1 (Core 2 Duo a 2.1 GHz, 2048 MB RAM, 120 GB HD).
- Sistema operativo: Windows Vista Ultimate.
- JDK 1.5.0_15
- Eclipse 3.5, con IAM.
3. Configuración del módulo batch.
He aquí el pom.xml del módulo app-batch, está comentado:
...com.autentia.training.maven appp-parent 1.0-SNAPSHOT com.autentia.training.maven app-batch 1.0-SNAPSHOT jar ...... com.autentia.training.maven app-core 1.0-SNAPSHOT mysql mysql-connector-java 5.0.5 maven-assembly-plugin src/main/assembly/installer.xml package-native install attached
A continuación el contenido del descriptor de empaquetado src/main/assembly/installer.xml:
installer zip false /lib runtime target lib app-batch-*-source.jar app-batch-*-javadoc.jar app-batch-*.jar target/site doc **/* src/main/config /config **/* src/main/bin /bin dos **/*.cmd src/main/bin /bin unix 0755 **/*.sh src/main/logs /logs
Con todo lo configurado necesitaremos mantener una estructura de directorios en el módulo batch similar a la que sigue:
Nuestra arquitectura de servicios está basada en Spring y JPA, de ahí la existencia de los ficheros de configuración de ambos frameworks.
4. El resultado del empaquetado.
Si invocamos al goal install de maven, en el directorio target del módulo batch encontraremos un fichero zip, con el nombre del módulo más el sufijo del identificador del assembly, en nuestro caso: app-batch-1.0-SNAPSHOT-installer.zip.
Dicho fichero comprimido es nuestra empaquetación del módulo batch, con todo lo necesario para ejecutar los procesos que hayamos programado. No tenemos más que descomprimir el zip en la máquina en la que queremos ejecutarlo, configurar los ficheros de entorno (acceso a la base de datos, propiedades individuales de la aplicación que ya tendremos configuradas en el módulo web,...) e invocar a los ejecutables de cada uno de los procesos.
5. Los scripts de los procesos batch.
Los ejecutables de los procesos batch simplemente invocarán a los métodos main de las clases que los implementen, pasándoles los parámetros que requieran por línea de comandos.
En este punto tenemos que resolver dos cuestiones:
- la carga dentro del classpath de ejecución de la máquina virtual de las librerías que han sido empaquetadas, para que todas estén disponibles en tiempo de ejecución,
- el paso de parámetros desde el script de ejecución de los procesos al método main de la clase que lo implementa
Estas cuestiones tienen diferentes soluciones en función del entorno.
5.1. UNIX.
El contenido del ejecutable de los procesos tendrá el siguiente código:#!/bin/sh PRGDIR=`dirname "$0"` # -- Prepare CLASSPATH ------------------------------------------------------- LOCALCLASSPATH=$CLASSPATH:$PRGDIR/../config for i in $PRGDIR/../lib/*.jar do LOCALCLASSPATH=$LOCALCLASSPATH:"$i" done # -- Invocation to client ------------------------------------------------------------ java -cp $LOCALCLASSPATH com.autentia.training.maven.client.TestClient $@
- la primera cuestión la resolvemos con un bucle, en el que vamos añadiendo a una variable local cada uno de los jar que distribuimos en el directorio lib, una línea más arriba ya hemos incluido el contenido del directorio config. Con -cp añadimos a la ejecución de la máquina virtual todo lo incluido en la variable local.
- con $@ resolvemos la cuestión del paso de parámetros del script a la clase.
5.2. Windows.
El contenido del ejecutable de los procesos tendrá el siguiente código:@echo off setlocal rem -- Check existence of JVM -------------------------------------------------- java -version >nul 2>&1 if errorlevel 1 goto :NO_JAVA rem -- Prepare CLASSPATH ------------------------------------------------------- call "%~dp0cp\atcp.cmd" %~dp0..\config for %%1 in ("%~dp0..\lib\*.jar") do call "%~dp0cp\atcp.cmd" %%1 rem -- Invocation to client ------------------------------------------------------------ echo. java -Xms256m -Xmx512m -XX:MaxPermSize=128m -cp "%CLASSPATH%"; com.autentia.training.maven.client.TestClient %* goto :END :NO_JAVA echo Java Virtual Machine not found, please add JRE's bin directory to PATH environment variable goto :END :END endlocal
- para resolver la primera cuestión volvemos a necesitar un bucle, pero ahora nos tenemos que apoyar en un segundo script atcp.cmd que vaya concatenando a la variable %CLASSPATH% una a una, la librería que itera. Con -cp añadimos a la ejecución de la máquina virtual todo lo incluido en la variable %CLASSPATH%.
- con %* resolvemos la cuestión del paso de parámetros del script a la clase.
El contenido del script atcp.cmd, es el siguiente:
@echo off set ARG=%1 shift :APPEND set ARG=%ARG% %1 shift if not "%1"=="" goto :APPEND @set CLASSPATH=%CLASSPATH%;%ARG%
6. Conclusiones.
Seguimos haciendo uso extensivo de maven para la gestión del ciclo de vida de nuestros proyectos y, aunque la primera intención pueda ser la de realizar este tipo de tareas manualmente, puesto que quizás sean puntuales o pensemos que total, seguro que tardo menos,... la experiencia nos dice que hacer las cosas de una manera controlada, a la larga, es mucho más beneficioso.
Tened en cuenta que si lo hacemos bien, nuestros procesos tendrían que estar documentados en el site, y eso se distribuye también en el zip, con lo que tendríamos cubiertas nuestras necesidades a la hora de ejecutarlos.
En cuanto a los ejecutables, más simple en Unix que en Windows... :-D, pero en ambos entornos "estamos abiertos a extensiones y cerrados a modificaciones" puesto que la inclusión de una librería a nuestra arquitectura o un parámetro adicional a nuestros procesos no implicarán modificación alguna en los scripts.
Un saludo.
Jose