En Gradle, ¿cómo declaro dependencias comunes en un solo lugar?

109

En Maven hay una característica muy útil cuando puede definir una dependencia en la <dependencyManagement>sección del POM principal y hacer referencia a esa dependencia de los módulos secundarios sin especificar la versión o el alcance o lo que sea.

¿Cuáles son las alternativas en Gradle?

Stanislav Bashkyrtsev
fuente

Respuestas:

179

Puede declarar dependencias comunes en un script principal:

ext.libraries = [ // Groovy map literal
    spring_core: "org.springframework:spring-core:3.1",
    junit: "junit:junit:4.10"
]

Desde un script secundario, puede usar las declaraciones de dependencia así:

dependencies {
    compile libraries.spring_core
    testCompile libraries.junit
}

Para compartir declaraciones de dependencia con opciones de configuración avanzadas, puede usar DependencyHandler.create:

libraries = [
    spring_core: dependencies.create("org.springframework:spring-core:3.1") {
        exclude module: "commons-logging"
        force = true
    }
]

Se pueden compartir varias dependencias con el mismo nombre:

libraries = [
    spring: [ // Groovy list literal
        "org.springframework:spring-core:3.1", 
        "org.springframework:spring-jdbc:3.1"
    ]
]

dependencies { compile libraries.spring } luego agregará ambas dependencias a la vez.

La única información que no puede compartir de esta manera es a qué configuración ( alcance en términos de Maven) se debe asignar una dependencia. Sin embargo, desde mi experiencia, es mejor ser explícito sobre esto de todos modos.

Peter Niederwieser
fuente
3
Gracias, esto resuelve mi pregunta, pero todavía tengo una preocupación ... En Maven podemos dejar la versión vacía y si se trata de una lib, es conveniente porque puede usarla en nuestra aplicación y hacer la gestión de dependencias para definir qué versión de la lib debería tomar. ¿Cómo harías lo mismo con Gradle?
Stanislav Bashkyrtsev
No entiendo la pregunta. Proporcione un ejemplo.
Peter Niederwieser
4
Peter, lo que ctapobep está diciendo es que en maven puedes declarar dependencias con versión (y alcance) en un pom principal (o agregador) en la sección dependencyManagement. Luego, en el pom "concreto", no es necesario volver a declarar la versión; solo artefacto y groupId. Básicamente, le dice a Maven "Necesito X: Y, pero use la versión que haya configurado el padre".
Michael Campbell
2
Para evitar este tipo de duplicación, que tienden a crear una separada dependencies.gradleguión donde defino todos mis dependencias como propiedades, por ejemplo: ext.GROOVY = 'org.codehaus.groovy:groovy-all:2.1.6'. En el proyecto raíz build.gradle, incluyo allprojects { apply from: "$rootDir/dependencies.gradle" }. Luego, todas las dependencias se definen en un archivo en lugar de distribuirlas, y se utilizan más constantes "fáciles de leer" en las configuraciones de dependencia.
Steinar
1
Eso es exactamente lo que hice arriba. No necesita postularse allprojectsporque las propiedades adicionales a nivel de proyecto son visibles para los subproyectos.
Peter Niederwieser
7

Es una respuesta tardía, pero es posible que también desee echar un vistazo a: http://plugins.gradle.org/plugin/io.spring.dependency-management Brinda la posibilidad de importar un 'bom' de maven y reutilizar las definiciones definido en el 'bom'. ¡Sin duda es una buena ayuda cuando se migra gradualmente de maven a gradle! Disfrutándolo ahora mismo.

habitacionesg
fuente
incluso es imprescindible cuando desee compartir las mismas dependencias en varios (múltiples) proyectos.
Roomsg
7
Aunque es conveniente, este complemento puede tener una huella de rendimiento significativa. Para 30 subproyectos con más de 200 dependencias, agrega hasta 1 minuto a la fase de resolución de dependencias. Sin embargo, para proyectos pequeños funciona como un encanto
Jk1
También anula las versiones de dependencia transitiva, digamos que ha declarado la versión 3.0.0 en la gestión de dependencias, pero para uno de los subproyectos necesita usar una versión anterior, por ejemplo, 2.5.0, entonces si tiene un proyecto que depende de este proyecto anterior, La dependencia transitiva se sobrescribirá de 2.5.0 a lo que se declara en el complemento de administración de dependencias, por lo que 3.0.0 en este caso es un comportamiento muy extraño
KameeCoding
7

A partir de Gradle 4.6, las restricciones de dependencia se sugieren en la documentación como la forma de lograr esto. De https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring_a_dependency_without_version :

Una práctica recomendada para proyectos más grandes es declarar dependencias sin versiones y usar restricciones de dependencia para la declaración de versión. La ventaja es que las restricciones de dependencia le permiten administrar versiones de todas las dependencias, incluidas las transitivas, en un solo lugar.

En su build.gradlearchivo principal :

allprojects {
  plugins.withType(JavaPlugin).whenPluginAdded {
    dependencies {
      constraints {
        implementation("com.google.guava:guava:27.0.1-jre")
      }
    }
  }
}

whenPluginAdded {No es estrictamente necesario envolver el bloque de dependencias con una comprobación del complemento de Java (... ), pero luego se encargará de agregar un proyecto que no sea de Java a la misma compilación.

Luego, en un proyecto infantil de Gradle, simplemente puede omitir la versión:

apply plugin: "java"

dependencies {
  implementation("com.google.guava:guava")
}

Las compilaciones secundarias aún pueden optar por especificar una versión superior. Si se especifica una versión inferior, se actualiza automáticamente a la versión de la restricción.

Adrian Baker
fuente
1
Se agregaron restricciones de dependencia en Gralde 4.6, por lo que esto funcionará con Gradle 4.6 o superior.
Jim Hurne
Creo que Gradle proporciona que el complemento de la plataforma Java se utiliza en tal caso. Sin embargo, la documentación de Gradle no es muy clara en este momento. Supongo que el uso de también allprojectsestá bien.
JojOatXGME
Quiero declarar las restricciones en el proyecto raíz, pero solo en uno de mis subproyectos, quiero cargar todas esas dependencias que tienen restricciones definidas.
dtc
2

io.spring.gradle:dependency-management-pluginEl plugin tiene problemas con la nueva serie Gradle 3.x pero es estable para la serie 2.x. Como referencia, consulte el informe de errores Soporte de caída para Gradle 3 # 115

En el caso de Spring ( principal promotor del uso de BOM ), puede terminar con:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath 'io.spring.gradle:dependency-management-plugin:1.0.0.RELEASE'
    }
}

repositories {
    mavenLocal()
    jcenter()
}

apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'

dependencyManagement {
    imports {
        mavenBom 'io.spring.platform:platform-bom:Athens-SR3'
    }
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'

    testCompile 'org.springframework.boot:spring-boot-starter-test'
}

Tenga en cuenta que io.spring.platform:platform-bomtiene org.springframework.boot:spring-boot-starter-parentcomo padre, por lo que es compatible con Spring Boot

Puede verificar la resolución de dependencia real a través de:

$ gradle dependencies
$ gradle dependencies --configuration compile
$ gradle dependencies -p $SUBPROJ

$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ

o con tarea:

task showMeCache {
    configurations.compile.each { println it }
}

Lea la publicación oficial del blog Soring Mejor administración de dependencias para Gradle para comprender el motivo de la introducción io.spring.gradle:dependency-management-plugin.

Gavenkoa
fuente
1

Puede centralizar una dependencia usando el siguiente código:

En gradle.properties

COMPILE_SDK_VERSION=26
BUILD_TOOLS_VERSION=26.0.1
TARGET_SDK_VERSION=26
MIN_SDK_VERSION=14

ANDROID_SUPPORT_VERSION=26.0.2

En cada módulo agregue a build.gradle:

android {
    compileSdkVersion COMPILE_SDK_VERSION as int
    buildToolsVersion BUILD_TOOLS_VERSION as String

    defaultConfig {
        minSdkVersion MIN_SDK_VERSION as int
        targetSdkVersion TARGET_SDK_VERSION as int
        versionCode 1
        versionName "1.0"

    }

}

dependencies {
 compile "com.android.support:appcompat-v7:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-v4:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-annotations:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:support-vector-drawable:${ANDROID_SUPPORT_VERSION}"
 compile "com.android.support:design:${ANDROID_SUPPORT_VERSION}"
}
Dhaval Jivani
fuente
0

Para mantener limpio su archivo gradle, podemos agrupar las dependencias en una matriz e implementarlas más tarde.

  1. Agregue una versión de bibliotecas como esta en build.gradle (nivel de aplicación) fuera del bloque de dependencia :

// declarar versiones de la biblioteca

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'
  1. Cree una matriz de dependencias relacionadas, para que pueda encontrarla fácilmente más tarde. Agréguelo en build.gradle (nivel de aplicación) fuera del bloque de dependencia :

// Utilizando la versión en la biblioteca y agregando dependencia junto con el nombre de acceso (como actualización (primera))

final networkDependencies = [
        retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
        retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
        retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
        okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
        okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]
  1. Y en bloque de dependencia :

// Implementar toda la dependencia de la matriz

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation networkDependencies.values()
}

Entonces, el código final se verá así:

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'

final networkDependencies = [
        retrofit             : "com.squareup.retrofit2:retrofit:${RetrofitVersion}",
        retrofitGsonConverter: "com.squareup.retrofit2:converter-gson:${RetrofitVersion}",
        retrofitRxJavaAdapter: "com.squareup.retrofit2:adapter-rxjava2:${RetrofitVersion}",
        okHttp3              : "com.squareup.okhttp3:okhttp:${OkHttpVersion}",
        okHttp3Logging       : "com.squareup.okhttp3:logging-interceptor:${OkHttpVersion}"
]

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation networkDependencies.values()
}
Suraj Vaishnav
fuente
¿Cómo incluir el procesador de anotaciones con esto? como en el caso de lombok
Pritish Joshi