Por lo general, en todo proyecto empresarial JAVA, surge al momento de definir la arquitectura del aplicativo, definir el concepto de modulo, subsistema, y por que no, sistema. Al momento de tomar estas definiciones con un aplicativo en particular, surgen muchas maneras de realizar esta división, pero si tenemos en mente el stack de tecnologías JAVA estándares, para la Web, en algún momento, sobre todo dependiendo del tamaño del proyecto, vamos a llegar a la pregunta del millón: conviene separar mi capa de presentación por módulos?
Desde el comienzo, incluido en todo lo que nos ofreció el stack de tecnologías para aplicaciones empresariales de JAVA, nunca hubo un buen soporte para realizar esto, que a simple vista resulta prácticamente básico, poder “partir” mi aplicación en módulos independientes, pero en cierta manera “unidos” entre si, mediante el concepto de aplicación empresarial. Si bien se podían embeber varios paquetes “war” dentro de un único bundle “ear”, eran aplicaciones prácticamente independientes, y, era muy difícil por ejemplo, reutilizar código, ya que un WAR no es una librería (JAR) como tal.
Con la aparición de Maven, el WAR comenzó a ser un módulo más, por lo que surgió naturalmente el concepto de tratarlo como un paquete de código en si. De todas maneras los primeros intentos por lograr la tan ansiada dependencia, no vinieron de los plugins “core” sino de terceros, por ejemplo el goal maven:uberwar de cargo, o el plugin warpath de AppFuse.
Estos plugins si bien lograban su cometido, no eran la forma más natural de poder establecer dependencias entre los módulos WAR y así lograr por ejemplo, la reutilización de código de capa de presentación.
Igualmente ustedes dirán, “pero si queremos reutilizar, porque no metemos el código en librerías JAR?”, el problema viene justamente por lo que decía al principio, hasta hace no tanto, el estándar JEE, no permitía que, por ejemplo, las páginas JSPs u otros recursos WEB vengan embebidas en librerías. Si podríamos reutilizar ese código y tener en un componente principal recursos comunes, y en otros componentes simplemente referenciarlos, se disminuiría un montón el código de varias aplicaciones similares o módulos de una aplicación grande.
Otro problema venía por el lado de las IDEs, si bien podíamos resolverlo quizá, con los plugins que mencioné anteriormente, la IDE por lo general no se “daba cuenta” de esta dependencia, y había que lograr que funcione usando trucos extraños.
La solución
Por suerte se logró solucionar este problema con la última versión del plugin que administra la construcción de archivos war de maven, el maven-war-plugin.
Ahora para poder reutilizar código, podemos usar tranquilamente la dependencia entre wars, que funciona de la siguiente manera.
Supongamos que tenemos un proyecto WAR, denominado “proyecto-comun”, el cual posee clases y recursos comunes a ser reutilizados en otros modulos WAR.Además tenemos un proyecto WAR, denominado “proyecto-nuevo”, el cual necesita reutilizar clases bases y recursos existentes en el proyecto anterior. Para lograr la dependencia, tenemos que agregar las siguientes configuraciones: En el “proyecto-comun”, debemos agregar lo siguiente en el pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<attachClasses>true</attachClasses>
<webModule>
<groupId>com.miempresa</groupId>
<artifactId>proyecto-comun</artifactId>
<contextRoot>/proyecto-comun</contextRoot>
</webModule>
</configuration>
</plugin>
Acá lo importante es el tag “attachClasses”, que le dice a maven que cree un artefacto secundario con las clases del proyecto, las que más adelante nos van a servir para poder compilar el mismo.
Luego en el “proyecto-nuevo”, tenemos que agregar lo siguiente:
<dependency>
<groupId>com.miempresa</groupId>
<artifactId>proyecto-comun</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>jar</type>
<classifier>classes</classifier>
</dependency>
<dependency>
<groupId>com.miempresa</groupId>
<artifactId>proyecto-comun</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>war</type>
</dependency>
La primer dependencia, indica que las clases se deben compilar teniendo en cuenta el JAR generado automáticamente por el primer proyecto, y la segunda, que luego de compilar, primero copie los recursos del war anterior y luego sobre ese, los recursos del war actual, reutilizando archivos jsps, css, imagenes, xmls, etc.
Lo bueno de esta técnica, es que funciona correctamente con Eclipse (por las dudas usar siempre la última versión), utilizando el plugin m2eclipse, que por el momento es lo mejorcito que existe para trabajar con proyectos maven. La IDE correctamente interpreta la dependencia, y si tenemos los dos proyectos importados, ni siquiera hay que ejecutar el comando “mvn install” sobre el “proyecto-comun” para que tome los cambios, los toma automáticamente.
Que falta
De todas maneras existen algunos puntos sin resolver todavía:
- No tenemos soporte para “mergear” el archivo web.xml, por lo que el web.xml del “proyecto-comun” va a ser pisado por el del “proyecto-nuevo”
- Hay que tener cuidado de no crear clases en los mismos paquetes y con los mismos nombres, porque van a ser ignoradas (suponiendo que el application server le de prioridad a las clases del directorio “classes”)
Igualmente es una mejora substancial con lo que había antes, y permite tratar el código de presentación, prácticamente como si se tratase de una librería común, respetando su propio ciclo de vida, relacionado a las versiones, empaquetado, etc.
0 comentarios:
Publicar un comentario