4. Maven#
Maven es un gestor de proyectos escritos en Java, esto es, una herramienta que automatiza la construcción y la gestión de aplicaciones escritas en Java, lo cual implica simplificar las tareas de creación, gestión de dependencias, compilación, pruebas, empaquetado y despliegue de la aplicación.
Para ello provee de una orden (mvn) provista de subórdenes que modularizan las distintas tareas de las que se encarga.
Nota
Visual Studio Code tiene una extensión que nos abstrae de todos estos comandos, por lo que este apéndice no tiene más interés qué tener una idea de qué es lo que subyace por debajo.
4.1. Creación#
Se impone una estructura estandarizada para el proyecto que podemos resumir en el siguiente gráfico:
+-- src
| +-- main/
| | +-- java/edu/acceso/miapp/ (Código de la aplicación)
| | +-- resources/ Archivos de configuración, etc.
| |
| +-- test/ Reproduce la estruct. de main para pruebas
|
+-- target/ Código generado
+-- pom.xml Configuración del proyecto.
El subcomando asociado a esta fase es archetype:generate
:
$ mvn archetype:generate -DgroupId=edu.acceso.test \
-DartifactId=miapp
-DarchetypeArtifactId=maven-archetype-quickstart \
-Dversion=1.0.0 \
-DinteractiveMode=false
Pero lo habitual es que el IDE nos abstraiga de esta fase y se encargue el mismo de ejecutar la orden cuando le pidamos iniciar el proyecto.
4.2. Dependencias#
También facilita el gestor la tarea de obtener las dependencias de nuestro
proyecto descargándolas directamente del Repositorio General de Maven. Basta
incluirla en pom.xml
. Por ejemplo:
<dependencies>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.2.0</version>
</dependency>
<!-- Otras dependencias -->
</dependencies>
La página tiene un buscador y puede buscarse a través de él la librería. La del ejemplo se haya en la dirección persistence-api, y escogiendo la versión deseada, se obtiene el código exacto que debe añadirse al archivo. Las librerías, además, pueden a su vez contener dependencias, pero se calculan si necesidad de incluirlas explícitamente.
La suborden asociada a la obtención de dependencias es:
$ mvn dependency:resolve
$ mvn dependency:tree # Muestra el árbol de dependencias.
Sin embargo, no es necesario efectuar esta operación explícitamente, porque se realiza automáticamente al realizar operaciones posteriores.
4.3. Compilación#
La compilación, esto es, la generación de bytecode se realiza a través del plugin maven-compiler-plugin. Hacer la operación, en principio, es sencillo:
$ mvn compile # Genera el bytecode.
$ mvn clean compile # Genera borrando antes el código generado previo
Ahora bien, hay distintas versiones de Java y, al respecto, el compilador (javac) necesita que se le indiquen dos cosas:
Para qué versión de Java se realiza la comprobación estática de código.
Para qué versión de Java se genera el bytecode[1].
En ausencia de configuración al respecto, el plugin le indica al compilador
que use para ambas cosas la antigua version 1.7[2], por lo que es muy
recomendable indicar explícitamente en el archivo pom.xml
una versión
algo más moderna, e indispensable si se van a usar características del lenguaje
más modernas. Puede hacerse como una propiedad:
<properties>
<maven.compiler.release>21</maven.compiler.release>
</properties>
o directamente configurando explíciamente el plugin (que en principio no necesita ser declarado):
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration>
<release>21</release>
</configuration>
</plugin>
</plugins>
</build>
Consejo
Configurarlo como propiedad permite usar el valor declarado de la versión en otras partes del archivo, que necesiten indicar también la versión. Por ejemplo, al configurar el plugin para generar la documentación con Javadoc.
Nota
La opción --release
que engloba ambos aspectos de la compilación
apareció en Java 9. Antes no existía y se usaban en su lugar --source
y
--target
(que, no obstante, siguen existiendo), por lo que si se quiere
mantener compatibilidad con un JDK antiguo podemos hacer:
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
o la configuración correspondiente directamente en el plugin.
4.4. Pruebas#
El código que prueba la aplicación debe escribirse bajo src/test/
con
la misma estructura que se uso en src/main/
.
Las subórdenes asociadas a esta fases son:
$ mvn test # Compila todo el código (principal y pruebas) y ejecuta las pruebas
$ mvn test-compile # Sólo compila las pruebas sin llegar a ejecutarlas.
4.5. Empaquetado#
El software compilado suele distribuirse en formato JAR, un archivo zip que
contiene las clases compiladas (archivos .class
) y algunos otros
archivos adicionales. Para crearlo:
$ mvn clean package
Para la generación del paquete, Maven usa el plugin maven-jar-plugin, que no incluye dependencias. Para más información sobre ello y cómo incluirlas consulte este gist sobre generación de paquetes.
Notas al pie