W3docs

Introducción a Java Maven

Qué es Maven, cómo construye proyectos Java y cómo instalar y ejecutar comandos mvn.

Introducción a Java Maven

Maven es la herramienta estándar de automatización de compilación y gestión de dependencias para Java. Convierte un proyecto en una descripción declarativa — qué es, de qué depende, cómo se construye — y luego ejecuta la compilación por usted. En lugar de gestionar a mano archivos JAR y opciones de javac, usted declara sus necesidades en un único archivo y Maven descarga las dependencias, compila, prueba y empaqueta su código a través de un ciclo de vida predecible y repetible.

El POM: un proyecto como datos

Todo proyecto Maven se describe mediante un pom.xml (Project Object Model). Identifica el proyecto con tres coordenadas — groupId, artifactId y version (juntas, el «GAV») — y enumera las bibliotecas que necesita. El mismo esquema de coordenadas nombra su proyecto y cada dependencia, que es como Maven localiza los artefactos en un repositorio.

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>shop-app</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <maven.compiler.release>21</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>6.1.0</version>
    </dependency>
  </dependencies>
</project>

El elemento <packaging> le dice a Maven qué producir (jar, war, pom). El bloque <properties> contiene valores reutilizables — aquí, la versión de Java a la que apunta el compilador.

Las dependencias y el classpath transitivo

Usted enumera solo sus dependencias directas. Maven lee el POM propio de cada dependencia e incorpora todo lo que ellas necesitan — las dependencias transitivas — construyendo el classpath completo automáticamente. Declarar spring-web también incorpora spring-core sin que usted lo nombre.

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.17.0</version>
</dependency>

Cada dependencia tiene un ámbito (scope) que controla cuándo está en el classpath. El valor predeterminado, compile, la hace disponible en todas partes; test la limita al código de prueba; provided significa que el entorno de ejecución la suministra.

ÁmbitoEn classpath de compilaciónEn classpath de pruebaEmpaquetadaUso típico
compile (predeterminado)Bibliotecas normales
providedNoAPI Servlet, suministrada en ejecución
runtimeNoControladores JDBC
testNoNoJUnit, Mockito

El ciclo de vida de la compilación

Las compilaciones de Maven se ejecutan a través de una secuencia fija de fases. Las fases clave del ciclo de vida predeterminado son validate, compile, test, package, verify, install y deploy. Ejecutar una fase ejecuta todas las fases anteriores a ella — mvn package primero valida, compila y prueba, y luego empaqueta. Nunca llama a las fases fuera de orden.

mvn compile          # compilar las fuentes principales
mvn test             # compilar + ejecutar pruebas unitarias
mvn package          # compilar + probar + construir el JAR/WAR
mvn install          # empaquetar + copiar el artefacto en su repositorio local
mvn clean package    # eliminar target/ primero, luego construir de cero

Cada fase está ligada a uno o más goals suministrados por plugins (por ejemplo, compiler:compile está ligado a la fase compile). En los plugins vive el trabajo real; el ciclo de vida solo lo ordena.

Los repositorios

Maven obtiene los artefactos de repositorios. Cuando usted compila, busca primero en su repositorio local (~/.m2/repository), una caché en su máquina. Ante una falta, descarga desde un repositorio remoto — por defecto Maven Central — y almacena una copia localmente para que la siguiente compilación sea rápida y sin conexión. Los equipos suelen añadir un repositorio privado para las bibliotecas internas.

pom.xml del proyecto  →  repo local (~/.m2)  →  repo remoto (Maven Central)
                         (¿acierto de caché?)    (descargar + cachear)

Un ejemplo ejecutable

El ejecutor de código no tiene Maven en su classpath, así que el programa siguiente modela la mecánica fundamental de Maven con simple código del JDK: almacena un POM diminuto como un map, resuelve el cierre transitivo de dependencias (eliminando duplicados de artefactos compartidos) y recorre el ciclo de vida de la compilación, deteniéndose en la fase solicitada. Las formas aquí — coordenadas GAV, resolución transitiva, fases ordenadas — son exactamente lo que hace el Maven real.

java— editable, runs on the server

Qué llevarse de la ejecución:

  • El proyecto y cada dependencia se nombran con el mismo triplete GAV, por eso Project coordinates: com.example:shop-app:1.0.0 se lee exactamente como una línea de dependencia.
  • Solo se declaran dos dependencias, pero el classpath resuelto tiene cuatro JARs — spring-core y jackson-annotations se incorporaron de forma transitiva, exactamente como hace Maven.
  • El conjunto seen garantiza que cada artefacto aparezca una sola vez; esta es la deduplicación de Maven que impide que una biblioteca compartida acabe dos veces en el classpath.
  • Executing: mvn package ejecuta validate, compile y test antes de package y luego se detiene — ejecutar una fase siempre ejecuta cada fase anterior en orden.
  • La compilación se detiene en package y nunca llega a install, reflejando cómo el goal solicitado acota hasta dónde avanza el ciclo de vida.

Práctica

Práctica

En Maven, ¿qué ocurre cuando se ejecuta 'mvn package'?