Frameworks a los chapazos: Maven (Parte 1/2)
Maven es una herramienta de software para la gestión y construcción de proyectos Java creada por Jason van Zyl, de Sonatype, en 2002. Es similar en funcionalidad a Apache Ant, pero tiene un modelo de configuración de construcción más simple, basado en un formato XML. (fuente: Wikipedia)
Antes de Maven
Cada proyecto solía definir su forma de incluir dependencias, definir versión del proyecto, de compilar desde una version de jre a la version target, como realizar pruebas unitarias, generar reportes, crear ejecutables a partir del código fuente y hasta como se debería hacer la entrega de ese ejecutable.
Todo esto conlleva a que los desarrolladores tuvieran que invertir mucho tiempo para poder sumarse a un proyecto y al final del día para poder entregar el ejecutable final. Luego de esto, vuelta a empezar...
Todo esto conlleva a que los desarrolladores tuvieran que invertir mucho tiempo para poder sumarse a un proyecto y al final del día para poder entregar el ejecutable final. Luego de esto, vuelta a empezar...
POM
El corazón de un proyecto manejado por maven es un fichero llamado
pom.xml
, que significa Project Object Model y debe encontrarse en la raíz de nuestro projecto.1 2 3 4 5 6 7 8 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.codehaus.mojo</groupId> <artifactId>my-project</artifactId> <version>1.0.0</version> </project> |
Las coordenadas maven
En el ejemplo anterior podemos ve que se definen las coordenas maven, la manera única de identificar a cualquier proyecto maven entre otro proyectos maven.
GroupId
: identifica a nuestra empresa o persona, y debe ser nuestro dominio invertido. Opcionalmente puede contener el grupo de aplicacionesArtifactId
: identifica a nuestro artefacto, nuestro proyecto o microservicio.version
: la version del proyecto mismo.
Adicionalmente podemos encontrar debajo de las coords nuestro
packaging
, el tipo de empaquetado que resulta de nuestro projecto, pudiendo ser jar
, war
, ear
o pom
, entre otras. Si no se espefica ninguno, tomará el por defecto: jar.Los ciclos de vida
Maven cuenta con 3 ciclos de vida predefinidos:
clean
, default
y site
Clean
: se encarga de eliminar la carpeta target básicamente.Default
: maneja el ciclo de vida pero de nuestro proyecto.Site
: se encarga de generar la documentación si es que la hubiera.
Cada uno de estos ciclos se puede ejecutar de manera independiente, aunque por lo general llamaremos al clean y a algunas de las fases de Default.
Fases de los ciclos de vida
Cada ciclo de vida de maven incluye fases progresivas, es decir que cada fase se ejecutará luego de haber ejecutado la anterior aunque no la llamemos.
Clean
pre-clean
: ejecuta los procesos necesarios para la limpieza.clean
: remueve todos los archivos generados en construcciones anteriores.post-clean
: finaliza los procesos de limpieza.
Default
validate
: valida que el proyecto sea correcto y la información esté disponible.compile
: compila el código fuente del proyecto.test
: ejecuta los test unitarios usando un framework de testing.package
: toma el código compilado y lo empaqueta en un formato distribuible, como un jar.verify
: corre los checks de las pruebas de integración para asegurar que la calidad haya sido alcanzada.install
: instala el empaqueta, según coordenadas, en el repository local para que otro proyecto pueda usarlo.deploy
: copia el empaqueta del repositorio local al repositorio remoto, si es que lo hubiera.
Site
pre-site
: ejecuta los procesos necesarios para esta fase.site
: genera la documentación del proyecto.post-site
: finaliza los procesos de esta fase y prepara el sitio para el despliegue.site-deploy
: despliega los archivos generados al servidor especificado.
Para el listado completo de las fases de cada ciclo visitar la documentación de maven aquí
Dependency Manager
Una de las caracteristicas más importantes de maven es la gestión de dependencias. Haciendo uso de las coordenadas podemos declaras dependencias para nuestro proyecto, estas se buscan en nuestro repo local y de no encontrarlas se descargán de maven central o repositorio que hayamos definido y luego se instalan en nuestro repositorio maven local para posterior uso. A continuación este ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> ... <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.7.1</version> <type>jar</type> <scope>test</scope> <optional>true</optional> </dependency> ... </dependencies> ... </project> |
Dependencias, dependencias transitivas y resolución de conflictos
Como buen gestor de dependencias maven se encarga de incluir a nuestro proyecto las dependencias que declaremos en el pom, asi como también de las dependencias transitivas, estas son las dependencias de nuestras dependencias para que estas puedan funcionar correctamente.
También se encarga de la resolución de conflictos, en el ejemplo de la imagen nuestras dependencias 1 y 2 dependen de B, de ser la misma versión sólo la incluirá una vez, de ser distintas versiones tomará la mas nueva como válida.
Scope, type, optional y exclusion
Dentro de la etiqueta
<project>
, declaramos una sección de <dependencies>
la cual incluye todas nuestras librerias envueltas con la etiqueta <dependency>
, está a su vez incluye:- Coordenadas: estas son obligatorias y se utilizan para identenficar una libreria.
type
: corresponde a la extensión del archivo. Es opcional y por defecto esjar
.scope
: se refiere a como encontrar la dependencia y de como agregarla al classpath de la aplicación. Hay 5 scopes disponibles:compile
: este es el valor por defecto si se omite, tiene que ser encontrada en el momento de la compilación y estará disponible en todos los classpath. Será propagada a los proyectos que dependan de esta.provided
: es similar a compile, pero indica que se espera que el JDK o un contenedor lo provea al momento de ejecución. Sólo está disponible en el classpath de compilación y test, y no es transitiva.test
: este scope indica que la dependencia no es requerida para el uso normal de la aplicación, y sólo esta disponible para las fases de compilación y ejecución pero de los tests. No es transitiva.runtime
: este scope indica que la dependencia no es requerida para la compilación, pero si en la ejecución. Estará en el classpath de ejecucion y test, pero no en el classpath de compilación.system
: es similar a provided excepto que tenés que proveer el JAR que lo contiene de manera explícita. El artefacto siempre está disponible y nunca será buscando en los repositorios.
optional
: Marca una dependencia como optional cuando este projecto en si mismo es una dependencia.
Más Maven
Aun quedan temas por cubrir como herencia, super POM, Standard Directory Layout, Repositorios, Plugins, Arquetipos, instalación