Introducción a Maven
Maven es una herramienta de gestión y comprensión de proyectos de software, principalmente utilizada en proyectos Java. Desarrollada por Apache Software Foundation, Maven proporciona a los desarrolladores una forma estandarizada de construir, empaquetar y distribuir software.
Los principales objetivos de Maven son:
- Simplificar el proceso de construcción
- Proporcionar un sistema de construcción uniforme
- Proporcionar información de calidad sobre el proyecto
- Fomentar mejores prácticas de desarrollo
Maven utiliza un archivo de configuración llamado POM
(Project Object Model) para describir el proyecto, sus dependencias y el proceso de construcción.
Conceptos principales de Maven
Project Object Model (POM)
El POM es un archivo XML que contiene información sobre el proyecto y detalles de configuración utilizados por Maven para construir el proyecto. Define el proyecto, sus dependencias, los plugins utilizados en el proceso de construcción, y mucho más.
Ejemplo básico de un archivo pom.xml:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId> <artifactId>my-project</artifactId> <version>1.0-SNAPSHOT</version>
<properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties>
<dependencies> <!-- Dependencias del proyecto --> </dependencies>
<build> <plugins> <!-- Plugins de building --> </plugins> </build></project>
Dependencias
Las dependencias son librerías externas que nuestro proyecto necesita para funcionar. Maven gestiona estas dependencias automáticamente, descargándolas de repositorios remotos cuando es necesario.
Ejemplo de cómo se declaran dependencias en el POM:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>6.1.12</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.11.0</version> <scope>test</scope> </dependency></dependencies>
Cada dependencia se identifica por su groupId
, artifactId
y version
. El elemento <scope>
define cuándo se necesita la dependencia (por ejemplo, solo para pruebas en el caso de junit).
Repositorios
Los repositorios son lugares donde Maven busca y descarga las dependencias. Existen tres tipos de repositorios:
- Repositorio local: Ubicado en nuestra computadora (por defecto en ~/.m2/repository).
- Repositorio central: El repositorio por defecto de Maven (https://repo.maven.apache.org/maven2/).
- Repositorios remotos: Repositorios personalizados definidos en el POM o en la configuración de Maven.
Ciclo de vida de construcción
Maven define un ciclo de vida de construcción estándar que consiste en una secuencia de fases. Las fases más comunes son:
validate
: Valida que el proyecto es correcto y toda la información necesaria está disponible.compile
: Compila el código fuente del proyecto.test
: Ejecuta las pruebas unitarias usando un framework de pruebas adecuado.package
: Empaqueta el código compilado en un formato distribuible (por ejemplo, JAR).verify
: Ejecuta cualquier comprobación sobre los resultados de las pruebas de integración para asegurar que se cumplen los criterios de calidad.install
: Instala el paquete en el repositorio local.deploy
: Copia el paquete final a un repositorio remoto.
Además, Maven tiene dos ciclos de vida especiales:
clean
: Para limpiar el proyecto y eliminar todos los archivos generados en la compilación anterior.site
: Para generar la documentación del proyecto.
Comandos básicos de Maven
mvn clean
: Limpia el directorio de salida.mvn compile
: Compila el código fuente.mvn test
: Ejecuta las pruebas.mvn package
: Empaqueta el código compilado.mvn install
: Instala el paquete en el repositorio local.mvn deploy
: Despliega el paquete en un repositorio remoto.mvn clean install
: Limpia, compila, prueba, empaqueta e instala el proyecto.mvn site
: Genera la documentación del sitio del proyecto.
Estructura de directorios estándar de Maven
Maven utiliza una estructura de directorios estándar:
Directorymi-proyecto/
Directorysrc/
Directorymain/
Directoryjava/
- …
Directoryresources/
- …
Directorytest/
Directoryjava/
- …
Directoryresources/
- …
Directorytarget/
- …
- pom.xml
src/main/java
: Código fuente principal.src/main/resources
: Recursos principales (archivos de configuración, propiedades, etc.).src/test/java
: Código fuente de pruebas.src/test/resources
: Recursos para pruebas.target
: Directorio donde Maven coloca los archivos compilados y empaquetados.pom.xml
: Archivo de configuración de Maven.
Creación de JARs ejecutables con Maven
Cuando se trabaja en un proyecto Java, a menudo se necesita crear un archivo JAR ejecutable que incluya todas las dependencias necesarias. Por defecto, el comando mvn package
crea un JAR, pero este no incluye las dependencias y no es directamente ejecutable. Para resolver esto, necesitamos configurar dos plugins importantes: Maven JAR Plugin
y Maven Shade Plugin
.
Maven JAR Plugin
El Maven JAR Plugin se utiliza para construir un JAR a partir de los archivos compilados y los recursos del proyecto.
El JAR Plugin es necesario para especificar la clase principal de nuestra aplicación, lo que permite que el JAR sea ejecutable.
Configuración
Añadimos lo siguiente a la sección <build><plugins>
de nuestro pom.xml
:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.mycompany.MainClass</mainClass> </manifest> </archive> </configuration></plugin>
Reemplazamos com.mycompany.MainClass
con la ruta completa a la clase principal.
Maven Shade Plugin
El Maven Shade Plugin
se utiliza para crear un “uber-JAR” o “fat JAR”, que es un JAR que incluye todas las dependencias de tu proyecto.
El Shade Plugin es crucial porque:
- Incluye todas las dependencias en un solo JAR, lo que facilita la distribución y ejecución de nuestra aplicación.
- Puede resolver conflictos de dependencias al reubicar clases.
- Minimiza el JAR resultante al eliminar archivos innecesarios.
Configuración
Añadimos lo siguiente a la sección <build><plugins>
de nuestro pom.xml
:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.mycompany.MainClass</mainClass> </transformer> </transformers> </configuration> </execution> </executions></plugin>
Nuevamente, reemplazamos com.mycompany.MainClass
con la ruta completa a la clase principal.
Cómo funciona
- El JAR Plugin se encarga de crear el JAR inicial y especificar la clase principal.
- El Shade Plugin toma este JAR y lo combina con todas las dependencias en un solo “uber-JAR”.
- Al ejecutar
mvn package
(o la opción de package en VS Code), Maven utilizará ambos plugins en el orden correcto para producir el JAR ejecutable final.
Ejecutando el JAR
Una vez que hayamos configurado estos plugins y ejecutado mvn package
, podremos ejecutar tu aplicación con:
java -jar target/tu-proyecto-1.0-SNAPSHOT.jar
O simplemente haciendo doble clic en el JAR si el sistema operativo lo permite.
Consideraciones adicionales
- Tamaño del JAR: El JAR resultante puede ser grande debido a la inclusión de todas las dependencias. Debemos considerar usar el Shade Plugin para minimizar el JAR si el tamaño es un problema.
- Conflictos de dependencias: El Shade Plugin puede ayudar a resolver conflictos de dependencias mediante la reubicación de clases. Debemos consultar la documentación del plugin para más detalles sobre cómo configurar esto.
- Licencias: Al incluir todas las dependencias en nuestro JAR, debemos asegurarnos de cumplir con las licencias de todas las bibliotecas que estás incluyendo.
Esta configuración te permitirá crear JARs ejecutables que incluyan todas las dependencias necesarias, facilitando la distribución y ejecución de tu aplicación Java.