Objetivo del tema
Aprenderás a modelar dependencias en Gradle, eligiendo repositorios, configuraciones y versiones adecuadas para mantener builds reproducibles y libres de conflictos.
Al finalizar, podrás añadir bibliotecas con distintos alcances, controlar variantes de versión y aplicar estrategias para resolver incompatibilidades entre artefactos.
Gradle descarga los artefactos desde repositorios definidos en el bloque repositories
. Algunos repositorios públicos concentran la mayoría de las bibliotecas, mientras que las organizaciones suelen agregar repositorios privados para publicar componentes propios.
repositories {
mavenCentral()
google()
maven {
name = "corporativo"
url = uri("https://repo.miempresa.com/releases")
credentials {
username = findProperty("repoUser") ?: System.getenv("REPO_USER")
password = findProperty("repoPassword") ?: System.getenv("REPO_PASS")
}
}
}
Cuando un repositorio requiere autenticación, utiliza credentials
y almacena los datos en propiedades externas o variables de entorno para no exponer credenciales.
Gradle organiza las dependencias según el momento en el que se necesitan. Las configuraciones más frecuentes en proyectos JVM son implementation
, api
, compileOnly
, runtimeOnly
y testImplementation
.
dependencies {
implementation "org.apache.httpcomponents.client5:httpclient5:5.3"
api "com.fasterxml.jackson.core:jackson-databind:2.17.1"
compileOnly "jakarta.annotation:jakarta.annotation-api:2.1.1"
runtimeOnly "ch.qos.logback:logback-classic:1.5.6"
testImplementation "org.junit.jupiter:junit-jupiter:5.10.2"
}
Elegir la configuración correcta evita exponer dependencias innecesarias y reduce el tamaño de los artefactos resultantes.
Gradle admite múltiples estrategias para declarar versiones. Las versiones fijas son ideales para reproducibilidad, pero también se pueden definir rangos o versiones dinámicas cuando se busca recibir actualizaciones automáticas.
1.+
o etiquetas latest.release
, lo que agiliza actualizaciones pero dificulta la trazabilidad.[1.2,2.0)
.dependencies {
implementation "io.github.resilience4j:resilience4j-circuitbreaker:2.2.0"
implementation "org.slf4j:slf4j-api:2.+" // versión dinámica
implementation "com.squareup.okhttp3:okhttp:[4.0,5.0)" // rango semántico
}
Si usas versiones dinámicas o rangos, considera habilitar dependencyLocking
para congelar las versiones resueltas en ambientes críticos.
Es habitual que dos dependencias transitivas necesiten distintas versiones de la misma biblioteca. Gradle resuelve por defecto eligiendo la versión más alta, pero se pueden definir exclusiones y reglas de resolución para mantener la compatibilidad.
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:3.3.0") {
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
}
implementation "org.springframework.boot:spring-boot-starter-jetty:3.3.0"
}
configurations.all {
resolutionStrategy {
force "com.google.guava:guava:33.0.0-jre"
eachDependency {
if (requested.group == "commons-logging") {
useVersion("1.2")
}
}
}
}
Las exclusiones evitan traer módulos innecesarios y resolutionStrategy
permite forzar versiones específicas, aplicar reglas condicionales o verificar hashes para reforzar la seguridad.
El manejo de dependencias en Gradle exige definir repositorios confiables, elegir configuraciones adecuadas y controlar las versiones que resuelve el build. Con las exclusiones y estrategias de resolución puedes asegurar compatibilidad entre bibliotecas y mantener builds reproducibles a medida que el proyecto escala.