Una dependencia es una biblioteca externa que tu proyecto necesita para compilar o ejecutarse. En lugar de reescribir código (análisis JSON, acceso a base de datos, pruebas…), se reutilizan bibliotecas contrastadas.
Maven gestiona estas dependencias automáticamente: las declaras en el pom.xml, y Maven las descarga y las coloca en el classpath.
| Sin Maven | Con Maven |
|---|---|
Descargar cada .jar a mano | Declarar 3 líneas en pom.xml |
| Gestionar el classpath manualmente | Maven lo construye automáticamente |
| Encontrar las bibliotecas compatibles | Resolución transitiva automática |
Una dependencia también se identifica por sus coordenadas GAV (
groupId:artifactId:version), exactamente como tu propio proyecto. Así es como Maven sabe qué descargar.
Las dependencias se declaran en el bloque <dependencies> del pom.xml. Cada dependencia es una etiqueta <dependency> con sus coordenadas GAV.
<dependencies>
<!-- Biblioteca Gson de Google para manipular JSON -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>Para encontrar las coordenadas correctas de una biblioteca, se consulta Maven Central (search.maven.org), que ofrece el bloque XML listo para copiar.
# Tras añadir una dependencia, se dispara la descarga
mvn compile
# O descargar de forma explícita sin compilar
mvn dependency:resolve| Elemento | Rol |
|---|---|
<groupId> | La organización que publica la biblioteca |
<artifactId> | El nombre de la biblioteca |
<version> | La versión deseada |
Maven pone las bibliotecas en caché en
~/.m2/repository. Una biblioteca ya descargada no se vuelve a descargar: por eso los builds siguientes son rápidos.
🔧 Mini-ejercicio — Declara la dependencia Gson (com.google.code.gson:gson:2.10.1) en un bloque <dependency>.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>El alcance (scope) de una dependencia indica cuándo y dónde está disponible: en la compilación, en las pruebas, en la ejecución, o la proporciona el entorno. Se precisa con <scope>.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope> <!-- disponible solo para las pruebas -->
</dependency>| Scope | Disponible en la compilación | Disponible en las pruebas | Disponible en la ejecución | Incluido en el artefacto |
|---|---|---|---|---|
compile (por defecto) | ✅ | ✅ | ✅ | ✅ |
test | ❌ | ✅ | ❌ | ❌ |
provided | ✅ | ✅ | ❌ (lo aporta el servidor) | ❌ |
runtime | ❌ | ✅ | ✅ | ✅ |
Ejemplos concretos:
| Biblioteca | Scope típico | Por qué |
|---|---|---|
| JUnit | test | Solo sirve para ejecutar las pruebas |
| API Servlet | provided | El servidor (Tomcat) ya la aporta |
| Controlador JDBC | runtime | Requerido en ejecución, no en la compilación |
| Gson | compile | Se usa en todo el código |
Poner JUnit en
compileen lugar detestes un error frecuente: embarca inútilmente la biblioteca de prueba en tu entregable final. Elige siempre el scope más restrictivo que convenga.
🔧 Mini-ejercicio — Declara una dependencia JUnit Jupiter (5.10.2) en alcance test en el pom.xml.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>Maven descarga las dependencias desde repositorios (repositories). Hay tres niveles:
| Tipo de repositorio | Descripción |
|---|---|
| Repositorio local | Caché en tu máquina: ~/.m2/repository |
| Maven Central | El repositorio público mundial, fuente por defecto |
| Repositorio privado | Servidor de empresa (Nexus, Artifactory) para bibliotecas internas |
Para añadir un repositorio privado, se declara en el pom.xml:
<repositories>
<repository>
<id>nexus-entreprise</id>
<url>https://nexus.monentreprise.com/repository/maven-public/</url>
</repository>
</repositories># Forzar la actualización de las dependencias desde los repositorios
mvn clean install -U
# Vaciar la caché de una biblioteca para forzar su nueva descarga
# (supresión manual de la carpeta correspondiente en ~/.m2)| Caso | Repositorio usado |
|---|---|
| Biblioteca open-source pública | Maven Central |
| Biblioteca casera de la empresa | Repositorio privado (Nexus/Artifactory) |
| Biblioteca ya descargada | Caché local ~/.m2 |
Las empresas usan a menudo un repositorio privado como espejo de Maven Central: acelera las descargas y permite controlar qué bibliotecas están autorizadas.
Una dependencia puede a su vez depender de otras bibliotecas: son las dependencias transitivas. Maven las descarga automáticamente — no tienes que listarlas.
Declaras una dependencia, Maven resuelve decenas:
<!-- Una sola declaración... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.5</version>
</dependency>
<!-- ...trae automáticamente spring-web, jackson, tomcat, etc. -->Para visualizar el árbol completo:
# Muestra el árbol de dependencias (directas + transitivas)
mvn dependency:treeSalida típica:
com.exemple:mon-app:jar:1.0.0
+- org.springframework.boot:spring-boot-starter-web:jar:3.2.5:compile
| +- org.springframework:spring-web:jar:6.1.6:compile
| +- com.fasterxml.jackson.core:jackson-databind:jar:2.15.4:compile
| \- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.20:compileCuando dos caminos traen dos versiones distintas de la misma biblioteca, Maven aplica la regla del «más cercano en el árbol» (nearest wins): gana la versión más cercana a tu proyecto.
La resolución transitiva es una de las mayores fuerzas de Maven: declaras tus intenciones de alto nivel, y Maven ensambla todo el puzle de dependencias por ti.
🔧 Mini-ejercicio — Escribe el comando que muestra el árbol completo de dependencias (directas y transitivas).
mvn dependency:treeA veces, una dependencia transitiva da problemas (conflicto de versión, biblioteca indeseada). Maven ofrece herramientas para diagnosticar y corregir.
Para excluir una dependencia transitiva no deseada:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>Comandos de diagnóstico útiles:
| Comando | Rol |
|---|---|
mvn dependency:tree | Muestra el árbol completo de dependencias |
mvn dependency:analyze | Detecta dependencias no usadas o faltantes |
mvn dependency:resolve | Descarga todas las dependencias |
# Localizar las dependencias declaradas pero no usadas,
# y las usadas pero no declaradas
mvn dependency:analyzeAntes de excluir nada, lanza
mvn dependency:treepara entender de dónde viene la dependencia problemática. Nunca se excluye a ciegas.
🔧 Mini-ejercicio — Escribe el comando que localiza las dependencias declaradas pero no usadas (y a la inversa).
mvn dependency:analyze¿Dónde pone Maven en caché las dependencias descargadas?
a) En target/
b) En ~/.m2/repository
c) En src/main/resources
d) En el servidor web
✅ Respuesta: b) — El repositorio local ~/.m2/repository sirve de caché: una biblioteca ya descargada no se vuelve a descargar.
¿Qué scope conviene a JUnit, una biblioteca usada solo para las pruebas?
a) compile
b) runtime
c) test
d) provided
✅ Respuesta: c) — El scope test deja la dependencia disponible solo para las pruebas y la excluye del entregable final.
¿Qué son las dependencias transitivas?
a) Dependencias que hay que listar a mano
b) Las dependencias de tus dependencias, resueltas automáticamente por Maven
c) Dependencias temporales
d) Dependencias de prueba
✅ Respuesta: b) — Una dependencia declarada trae sus propias dependencias; Maven las descarga automáticamente.
¿Qué comando muestra el árbol completo de dependencias?
a) mvn list
b) mvn dependency:tree
c) mvn show-deps
d) mvn package
✅ Respuesta: b) — mvn dependency:tree muestra las dependencias directas y transitivas, útil para diagnosticar conflictos.
¿Qué scope elegir para la API Servlet, que aporta el servidor Tomcat?
a) compile
b) test
c) provided
d) runtime
✅ Respuesta: c) — provided: la biblioteca hace falta para compilar, pero el entorno de ejecución (el servidor) ya la aporta.
~/.m2/repository.test y no entra en el entregable.mvn dependency:tree muestra el árbol completo.provided porque Tomcat ya la aporta.En un proyecto existente, añade dos dependencias: Gson (com.google.code.gson:gson:2.10.1) en alcance compile para manipular JSON, y JUnit Jupiter (org.junit.jupiter:junit-jupiter:5.10.2) en alcance test. Luego verifica el árbol de dependencias.
<dependencies> esperado<dependencies>
<!-- Gson: usada en todo el código (scope compile por defecto) -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<!-- JUnit: solo pruebas -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>Verificación:
# Descargar y mostrar el árbol de dependencias
mvn dependency:treeResultado esperado:
com.exemple:mon-app:jar:1.0.0-SNAPSHOT
+- com.google.code.gson:gson:jar:2.10.1:compile
\- org.junit.jupiter:junit-jupiter:jar:5.10.2:test
+- org.junit.jupiter:junit-jupiter-api:jar:5.10.2:test
+- org.junit.jupiter:junit-jupiter-params:jar:5.10.2:test
\- org.junit.jupiter:junit-jupiter-engine:jar:5.10.2:testFíjate en que
junit-jupitertrae automáticamente-api,-paramsy-engine: son sus dependencias transitivas. Solo declaraste una línea, Maven resolvió el resto.
<dependencies>; Maven la descarga y la pone en caché en ~/.m2.compile, test, provided, runtime) controlan cuándo está disponible la dependencia.~/.m2), Maven Central (público), privado (Nexus/Artifactory).mvn dependency:tree permite inspeccionarla.Lección 04 — Ciclo de vida y fases: entender las fases (compile, test, package, install, deploy) que orquestan la construcción.
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