Repositorios, coordenadas de dependencias y la plataforma BOM
Dónde busca Gradle las librerÃas, cómo nombrarlas y cómo alinear versiones con un BOM.
Cada librerÃa externa que usa tu proyecto Kotlin tiene que descargarse de algún lugar, y un **repositorio** es ese "lugar": un servidor que aloja artefactos publicados. Declaras los repositorios en el bloque `repositories { }`, y el orden importa: Gradle consulta cada repositorio de arriba abajo y se detiene en el primero que tenga el artefacto. La entrada más común es `mavenCentral()`, el repositorio público canónico para librerÃas de la JVM y de Kotlin. Para Android y muchas librerÃas de Google también se agrega `google()`. Ambos son atajos de conveniencia que se expanden a URLs conocidas, asà que casi nunca escribes la URL a mano.
Cuando una librerÃa no está en un repositorio público — un Nexus o Artifactory corporativo interno, un feed de GitHub Packages o el servidor privado de un proveedor — la declaras explÃcitamente con un bloque `maven { }` y una `url`. Puedes añadir credenciales y filtros de contenido: `credentials { }` provee un usuario y contraseña (idealmente leÃdos desde `gradle.properties` o variables de entorno en vez de escribirlos en duro), y `content { }` te permite restringir un repositorio solo a ciertos grupos para que Gradle no malgaste consultas pidiéndole artefactos públicos a un servidor privado. En Gradle moderno el lugar preferido para los repositorios es `dependencyResolutionManagement` dentro de `settings.gradle.kts`, que los centraliza para todos los módulos del build.
Una dependencia se identifica por sus **coordenadas** con la forma `group:name:version`. El *group* es un espacio de nombres en DNS inverso que identifica al publicador (por ejemplo `org.jetbrains.kotlinx`), el *name* es el artefacto especÃfico (`kotlinx-coroutines-core`), y la *version* fija qué release quieres (`1.8.1`). Juntos se mapean a una ruta única en el repositorio. En el DSL de Kotlin normalmente lo pasas como una sola cadena — `implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")` — aunque Gradle también acepta la forma con argumentos nombrados `group = ..., name = ..., version = ...` cuando necesitas definir los campos programáticamente.
Escribir versiones en duro por todos lados es frágil, asà que Gradle te da varias formas de expresar *qué* versión. Una versión fija como `1.8.1` es la opción más segura y reproducible. Una **versión dinámica** como `1.8.+` o el especial `latest.release` le dice a Gradle que resuelva la coincidencia más nueva en tiempo de build — cómodo pero no determinista, por lo que se desaconseja en builds de producción. Un **rango de versiones** como `[1.5,2.0)` acepta cualquier versión desde 1.5 inclusive hasta 2.0 sin incluirla; el corchete significa inclusivo y el paréntesis exclusivo, igual que la notación estándar de intervalos. Los rangos cambian reproducibilidad por flexibilidad, asà que la mayorÃa de los equipos prefiere versiones fijas más un catálogo de versiones.
Un **BOM** (Bill of Materials) resuelve el problema relacionado de mantener una *familia* de librerÃas en versiones mutuamente compatibles. Importas un BOM con `platform("group:name:version")`, y luego declaras los miembros de la familia **sin versión** — el BOM la provee. Asà mantienes en sincronÃa todos los módulos de Spring, Jackson o kotlinx: subes una versión del BOM y todas las dependencias gobernadas se mueven juntas. Un `platform()` es un proveedor de restricciones, no una dependencia normal, asà que por sà solo no añade nada a tu classpath; solo influye en la resolución de versiones.
Por último, los proyectos Gradle modernos centralizan todo esto en un **catálogo de versiones**, el archivo `gradle/libs.versions.toml`. El catálogo define las tablas `[versions]`, `[libraries]` y `[plugins]`, y tus scripts de build las referencian con el accesor tipado `libs` (por ejemplo `implementation(libs.coroutines.core)`). Los catálogos te dan una única fuente de verdad, autocompletado en el IDE y actualizaciones de versión fáciles en un build multimódulo — y se combinan limpiamente con los BOMs de `platform()` para las librerÃas que publican uno.
// settings.gradle.kts — centralize repositories for every moduledependencyResolutionManagement {repositories {mavenCentral() // public JVM/Kotlin artifactsgoogle() // Android & Google librariesmaven { // private/internal serverurl = uri("https://nexus.example.com/repository/maven-releases/")credentials {username = providers.gradleProperty("nexusUser").orNullpassword = providers.gradleProperty("nexusPass").orNull}content { includeGroup("com.example.internal") } // only ask here for our group}}}
Declare where Gradle resolves dependencies, including a credentialed private repo.
// build.gradle.kts — coordinates, a version range, and a BOM platformdependencies {// group:name:version as a single coordinate stringimplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")// version range: >= 3.12.0 and < 4.0.0implementation("org.apache.commons:commons-lang3:[3.12.0,4.0.0)")// import a BOM, then add family members WITHOUT versionsimplementation(platform("com.fasterxml.jackson:jackson-bom:2.17.1"))implementation("com.fasterxml.jackson.module:jackson-module-kotlin") // version from BOM}
Pin a version, use a range, and let a BOM govern a whole library family.
# gradle/libs.versions.toml — type-safe version catalog[versions]coroutines = "1.8.1"jackson = "2.17.1"[libraries]coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }jackson-bom = { module = "com.fasterxml.jackson:jackson-bom", version.ref = "jackson" }jackson-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin" } # version via BOM# Used as: implementation(libs.coroutines.core); implementation(platform(libs.jackson.bom))
One source of truth for versions, referenced via the type-safe libs accessor.
🧠Comprueba tu comprensión
0/1 · 0/1 answered1. You import a BOM with `implementation(platform("com.fasterxml.jackson:jackson-bom:2.17.1"))`. What is the correct way to then declare `jackson-module-kotlin`?