4 - Dependencias y repositorios

Objetivo del tema

En este tema aprenderás a declarar dependencias en Apache Maven, gestionar versiones, comprender los alcances disponibles, centralizar configuraciones con dependencyManagement, interactuar con repositorios remotos y resolver conflictos derivados de dependencias transitivas.

4.1 Declarar dependencias en pom.xml

Las dependencias se definen en la sección <dependencies> del POM. Cada objeto describe las coordenadas del artefacto deseado: groupId, artifactId y version. Maven descarga el artefacto desde el repositorio correspondiente y lo agrega al classpath según su alcance.

<dependencies>
  <dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>33.1.0-jre</version>
  </dependency>
</dependencies>
  • Cada dependencia se resuelve una única vez y se almacena en el repositorio local para reutilizarla en futuras compilaciones.
  • Para conocer las coordenadas exactas puedes consultar catálogos como Maven Central.
  • El uso de versiones explícitas evita resultados impredecibles durante las construcciones.

4.2 Versionado de dependencias

Elegir versiones adecuadas es clave para garantizar estabilidad y compatibilidad. Maven permite fijar versiones exactas, emplear sufijos o utilizar rangos para admitir varias variantes.

  • Versiones exactas: definen un artefacto específico y son la opción recomendada para entornos productivos.
  • Versiones con sufijo SNAPSHOT: apuntan a compilaciones en desarrollo; siempre descargan la última versión disponible.
  • Rangos: expresiones como [1.0,2.0) permiten aceptar versiones dentro de un intervalo, aunque requieren análisis para evitar incompatibilidades.

Unifica las versiones mediante propiedades para facilitar actualizaciones globales y minimizar el riesgo de divergencias.

4.3 Alcances de dependencias

El atributo <scope> determina en qué fases del ciclo de vida se usará la dependencia y si se empaquetará dentro del artefacto final.

  • compile: valor por defecto; disponible en compilación, pruebas y ejecución del artefacto resultante.
  • test: visible solo durante pruebas; no se incluye en el empaquetado.
  • runtime: requerido en ejecución pero no en compilación (por ejemplo, drivers de base de datos).
  • provided: asumido por el entorno de despliegue, como un contenedor de servlets.
  • system: similar a provided, pero exige referenciar un JAR en el sistema de archivos; su uso está desaconsejado.
  • import: exclusivo de dependencyManagement para importar bill of materials (BOMs).

Seleccionar el alcance correcto evita empaquetar bibliotecas innecesarias y reduce conflictos en tiempo de ejecución.

4.4 Gestión de versiones con dependencyManagement

La sección <dependencyManagement> permite centralizar versiones sin agregarlas automáticamente al classpath. Los módulos hijos pueden declarar dependencias sin especificar versión y heredar los valores fijados.

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>3.2.5</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
  • Importar un BOM garantiza que todas las dependencias de un ecosistema compartan versiones compatibles.
  • Los proyectos hijos deben declarar la dependencia con sus coordenadas, pero pueden omitir la versión para utilizar la heredada.
  • Este enfoque simplifica la actualización de librerías en proyectos multi-módulo.

4.5 Repositorios remotos y privados

Además del repositorio central, Maven puede consultar repositorios remotos adicionales definidos en el POM o en settings.xml. Esto es común en organizaciones que alojan componentes internos o espejos de artefactos públicos.

<repositories>
  <repository>
    <id>repositorio-interno</id>
    <url>https://artifactory.miempresa.com/maven-release</url>
    <releases>
      <enabled>true</enabled>
    </releases>
    <snapshots>
      <enabled>false</enabled>
    </snapshots>
  </repository>
</repositories>
  • Los repositorios privados suelen administrarse con herramientas como Nexus Repository o Artifactory para controlar el acceso y aplicar políticas de liberación.
  • Configura las credenciales en settings.xml mediante la sección <servers> para evitar exponerlas en el POM.
  • Puedes definir diferentes repositorios para versiones liberadas y SNAPSHOT con reglas de habilitación independientes.

4.6 Dependencias transitivas y cómo resolver conflictos

Cuando una dependencia incluye otras bibliotecas, Maven las incorpora de forma transitiva. Aunque esto simplifica la configuración, puede provocar conflictos de versión o inclusiones innecesarias.

  • Usa mvn dependency:tree para visualizar el grafo completo y detectar origenes de cada dependencia.
  • Excluye artefactos concretos mediante la etiqueta <exclusion> dentro de la dependencia que los trae.
  • Fija la versión deseada en <dependencyManagement> para forzar la resolución cuando existen versiones divergentes.
  • Evalúa el tamaño final del artefacto y la seguridad de las bibliotecas transitivas usando plugins como maven-dependency-plugin o OWASP Dependency-Check.

Gestionar activamente las dependencias transitivas evita incompatibilidades en ejecución y permite cumplir políticas de seguridad corporativas.

Resumen didáctico

Maven ofrece mecanismos declarativos para controlar dependencias y repositorios: desde la simple declaración en el POM hasta la centralización con dependencyManagement y el uso de repositorios privados. Comprender los alcances, el versionado y la gestión de transitividades es crucial para construir artefactos consistentes y seguros.