El pom.xml (Project Object Model) es el archivo central de todo proyecto Maven. Es un documento XML que describe el proyecto: su identidad, sus dependencias, sus propiedades y la forma de construirlo.
Todo pom.xml empieza por una raíz <project> con su espacio de nombres, y declara obligatoriamente la versión del modelo:
<?xml version="1.0" encoding="UTF-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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- El resto de la configuración aquí -->
</project>
<modelVersion>4.0.0</modelVersion>es obligatorio y vale siempre4.0.0hoy: es la versión del formato de archivopom.xml, no la versión de tu proyecto.
Un pom.xml se lee de arriba abajo, por grandes bloques. Esta es la organización típica:
| Bloque | Rol |
|---|---|
<modelVersion> | Versión del formato (siempre 4.0.0) |
<groupId> / <artifactId> / <version> | Coordenadas (identidad del proyecto) |
<packaging> | Tipo de artefacto (jar, war, pom) |
<properties> | Variables reutilizables (versiones, codificación) |
<dependencies> | Las bibliotecas usadas (lección 03) |
<build> | Plugins y configuración de construcción |
El bloque <packaging> determina el tipo de entregable:
| Valor | Producto |
|---|---|
jar | Biblioteca o aplicación Java (por defecto) |
war | Aplicación web desplegable en un servidor |
pom | Proyecto «parent» sin código (agregador) |
Si omites
<packaging>, Maven eligejarpor defecto. Una vez más: convención antes que configuración.
🔧 Mini-ejercicio — Escribe la etiqueta <packaging> para producir una aplicación web desplegable en Tomcat.
<packaging>war</packaging>Todo proyecto Maven se identifica de forma única por tres coordenadas, a menudo abreviadas GAV: GroupId, ArtifactId, Version.
<groupId>com.exemple</groupId>
<artifactId>mon-app</artifactId>
<version>1.0.0</version>| Coordenada | Significado | Convención |
|---|---|---|
| groupId | La organización / el proyecto | Nombre de dominio invertido: com.exemple |
| artifactId | El nombre del módulo | Corto, en minúsculas: mon-app |
| version | La versión actual | Numérica: 1.0.0, o 1.0.0-SNAPSHOT |
El sufijo -SNAPSHOT merece una atención especial:
| Versión | Sentido |
|---|---|
1.0.0-SNAPSHOT | Versión en desarrollo, inestable, actualizada con frecuencia |
1.0.0 | Versión publicada (release), fijada e inmutable |
# El nombre del artefacto producido combina artifactId + version
# Ej.: mon-app-1.0.0-SNAPSHOT.jar
mvn packageLa combinación
groupId:artifactId:versiones la «dirección postal» de tu proyecto en el ecosistema Maven. Así es como otros proyectos podrán depender de él.
🔧 Mini-ejercicio — Escribe las tres etiquetas GAV para un proyecto com.banque llamado gestion-comptes en versión de desarrollo 1.0.0.
<groupId>com.banque</groupId>
<artifactId>gestion-comptes</artifactId>
<version>1.0.0-SNAPSHOT</version>El bloque <properties> define variables reutilizables en todo el pom.xml. Ahí se centralizan las versiones y los ajustes para evitar repeticiones.
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.10.2</junit.version>
</properties>Luego se reutiliza una propiedad con la sintaxis ${nom}:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version> <!-- reutiliza la propiedad -->
<scope>test</scope>
</dependency>Propiedades habituales:
| Propiedad | Rol |
|---|---|
maven.compiler.source / target | Versión Java del código fuente y del bytecode |
project.build.sourceEncoding | Codificación de los archivos (siempre UTF-8) |
Propiedades personalizadas (junit.version…) | Centralizar los números de versión |
Centralizar las versiones en
<properties>es una buena práctica: para pasar JUnit de 5.10 a 5.11, modificas un solo lugar en lugar de cada dependencia.
🔧 Mini-ejercicio — Define una propiedad gson.version con valor 2.10.1, luego muestra cómo reutilizarla en una etiqueta <version>.
<properties>
<gson.version>2.10.1</gson.version>
</properties>
<!-- ... -->
<version>${gson.version}</version>Un pom.xml puede heredar de otro pom.xml mediante el bloque <parent>. El hijo recupera entonces las propiedades, dependencias y configuraciones del parent. Es el mecanismo que permite factorizar la configuración común a varios módulos.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- vacío: buscar el parent en el repositorio -->
</parent>El uso más conocido es el parent Spring Boot, que fija las versiones de decenas de bibliotecas para que sean compatibles entre sí. Gracias a él, declaras dependencias sin precisar su versión:
<!-- Sin <version>: se hereda del parent -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>| Con herencia parent | Sin herencia parent |
|---|---|
| Versiones coherentes garantizadas | Riesgo de versiones incompatibles |
| Menos configuración repetida | Todo que redeclarar en cada módulo |
El parent Spring Boot actúa como una «lista de la compra validada»: garantiza que todas tus bibliotecas se entienden bien, sin que tengas que elegir cada número de versión a mano.
Aquí va un pom.xml realista que reúne todo lo anterior: coordenadas, propiedades, parent opcional y dependencias.
<?xml version="1.0" encoding="UTF-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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- Versión del formato de archivo -->
<modelVersion>4.0.0</modelVersion>
<!-- Coordenadas GAV: identidad del proyecto -->
<groupId>com.exemple</groupId>
<artifactId>mon-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- Variables reutilizables -->
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.10.2</junit.version>
</properties>
<!-- Bibliotecas usadas -->
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>Se puede mostrar el pom.xml «efectivo» (con toda la herencia resuelta):
# Muestra el pom completo, parent incluido
mvn help:effective-pomEl comando
mvn help:effective-pomes valioso para entender lo que Maven «ve» de verdad, incluido todo lo que viene del parent.
🔧 Mini-ejercicio — Escribe el comando que muestra el pom.xml efectivo, con toda la herencia del parent resuelta.
mvn help:effective-pom¿Qué valen las tres coordenadas GAV?
a) Group, Action, Value
b) GroupId, ArtifactId, Version
c) Git, Apache, Version
d) General, Application, Version
✅ Respuesta: b) — GAV = groupId, artifactId, version: la identidad única del proyecto.
¿Qué significa el sufijo -SNAPSHOT en una versión?
a) Una versión publicada y fijada
b) Una versión en desarrollo, inestable y actualizada con frecuencia
c) Una captura de pantalla del proyecto
d) Una versión obsoleta
✅ Respuesta: b) — -SNAPSHOT indica una versión de desarrollo. Una versión sin ese sufijo es una release fijada.
¿Para qué sirve el bloque <properties>?
a) Para declarar las dependencias
b) Para definir variables reutilizables (versiones, codificación) con ${...}
c) Para configurar el servidor web
d) Para escribir el código Java
✅ Respuesta: b) — Las propiedades centralizan valores reutilizables mediante la sintaxis ${nom}, evitando repeticiones.
¿Cuál es la ventaja de heredar de un <parent> como spring-boot-starter-parent?
a) Elimina la necesidad de código
b) Garantiza versiones de bibliotecas coherentes y reduce la configuración
c) Acelera la red
d) Cifra el pom.xml
✅ Respuesta: b) — El parent fija versiones compatibles entre sí; entonces se pueden declarar dependencias sin precisar su versión.
¿Qué valor toma siempre <modelVersion> hoy?
a) 1.0.0
b) 3.9.6
c) 4.0.0
d) 17
✅ Respuesta: c) — <modelVersion>4.0.0</modelVersion> es la versión del formato de archivo pom.xml, obligatoria e invariable.
groupId, artifactId, version: identidad única del proyecto.-SNAPSHOT marca una versión en desarrollo; sin sufijo es una release fijada.<properties> centraliza variables reutilizables con ${...}.<modelVersion> vale siempre 4.0.0.Redacta desde cero un pom.xml para un proyecto identificado por com.banque:gestion-comptes:1.0.0-SNAPSHOT, empaquetado en jar, compilado en Java 17 con codificación UTF-8, y que centralice la versión de JUnit en una propiedad. Luego verifícalo.
<?xml version="1.0" encoding="UTF-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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.banque</groupId>
<artifactId>gestion-comptes</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.10.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>Verificación:
# Verifica que el pom es válido y resoluble
mvn validate
# Muestra el pom efectivo (parent y propiedades resueltos)
mvn help:effective-pomResultado esperado:
[INFO] BUILD SUCCESSSi
mvn validatemuestraBUILD SUCCESS, tupom.xmles sintácticamente correcto y todas sus coordenadas están bien formadas. Un error frecuente: olvidar<modelVersion>o cerrar mal una etiqueta XML.
pom.xml es un archivo XML que describe identidad, propiedades, dependencias y build.groupId, artifactId, version) identifican el proyecto de forma única.-SNAPSHOT = versión en desarrollo; sin sufijo = versión publicada y fijada.<properties> centralizan variables reutilizables mediante ${nom}.<parent> factoriza la configuración y garantiza versiones coherentes.Lección 03 — Gestión de las dependencias: declarar bibliotecas, entender los alcances, los repositorios y la resolución transitiva.
Todos los derechos reservados. Toda reproducción, difusión, uso o adaptación de este curso, en todo o en parte, está estrictamente prohibida sin la autorización escrita previa del Dr. Haythem REHOUMA.
Curso creado por Dr. Haythem REHOUMA — Desarrollo y despliegue de soluciones de datos