In Gradle, come dichiaro le dipendenze comuni in un unico posto?


109

In Maven è disponibile una funzionalità molto utile quando è possibile definire una dipendenza nella <dependencyManagement>sezione del POM genitore e fare riferimento a tale dipendenza dai moduli figlio senza specificare la versione o l'ambito o altro.

Quali sono le alternative a Gradle?

Risposte:


179

Puoi dichiarare dipendenze comuni in uno script genitore:

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

Da uno script figlio, puoi quindi utilizzare le dichiarazioni di dipendenza in questo modo:

dependencies {
    compile libraries.spring_core
    testCompile libraries.junit
}

Per condividere dichiarazioni di dipendenza con opzioni di configurazione avanzate, puoi usare DependencyHandler.create:

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

Più dipendenze possono essere condivise con lo stesso nome:

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

dependencies { compile libraries.spring } aggiungerà quindi entrambe le dipendenze contemporaneamente.

L'unica informazione che non è possibile condividere in questo modo è la configurazione ( ambito in termini di Maven) a cui deve essere assegnata una dipendenza. Tuttavia, dalla mia esperienza è meglio essere espliciti su questo comunque.


3
Grazie, questo risolve la mia domanda, ma ho ancora una preoccupazione però .. In Maven possiamo lasciare la versione vuota e se questa è una lib, è conveniente perché puoi usarla nella nostra app e fare dependencyManagement per definire quale versione della lib dovrebbe prendere. Come faresti lo stesso con Gradle?
Stanislav Bashkyrtsev

Non capisco la domanda. Fornisci un esempio.
Peter Niederwieser

4
Peter, quello che sta dicendo ctapobep è che in Maven puoi dichiarare le dipendenze con versione (e ambito) in un genitore (o aggregatore) pom nella sezione dependencyManagement. Quindi nel pom "concreto", non è necessario dichiarare nuovamente la versione; solo artefatto e groupId. Fondamentalmente dice a Maven "Ho bisogno di X: Y, ma usa la versione che il genitore ha configurato".
Michael Campbell

2
Per evitare questo tipo di duplicazione, tendo a creare un separato dependencies.gradlescript in cui definisco tutte le mie dipendenze come proprietà, come ad esempio: ext.GROOVY = 'org.codehaus.groovy:groovy-all:2.1.6'. Nel progetto radice build.gradle, includo allprojects { apply from: "$rootDir/dependencies.gradle" }. Quindi tutte le dipendenze vengono definite in un file invece di distribuirle e vengono utilizzate costanti più "facili da leggere" nelle configurazioni delle dipendenze.
Steinar

1
È esattamente quello che ho fatto sopra. Non è necessario applicare a allprojectsperché le proprietà extra a livello di progetto sono visibili ai sottoprogetti.
Peter Niederwieser

7

È una risposta in ritardo, ma potresti anche voler dare un'occhiata a: http://plugins.gradle.org/plugin/io.spring.dependency-management Fornisce la possibilità di importare un "bom" esperto e riutilizzare le definizioni definito nel "bom". È sicuramente un bel aiuto quando si passa gradualmente da maven a gradle! Mi sto divertendo adesso.


è anche un must-have quando vuoi condividere le stesse dipendenze tra diversi (multi) progetti.
roomsg

7
Sebbene conveniente, questo plugin potrebbe avere un impatto significativo sulle prestazioni. Per 30 sottoprogetti con oltre 200 dipendenze, aggiunge fino a 1 minuto alla fase di risoluzione delle dipendenze. Per i piccoli progetti funziona a
meraviglia

sovrascrive anche le versioni delle dipendenze transitive, supponiamo di aver dichiarato la versione 3.0.0 nella gestione delle dipendenze, ma per uno dei sottoprogetti è necessario utilizzare una versione precedente, ad esempio 2.5.0, quindi se si dispone di un progetto dipendente da questo progetto precedente il la dipendenza transitiva verrà sovrascritta da 2.5.0 a quanto dichiarato nel plug-in di gestione delle dipendenze, quindi 3.0.0 in questo caso un comportamento molto strano
KameeCoding

7

A partire dal Grado 4.6, i vincoli di dipendenza sono suggeriti nella documentazione come modo per ottenere questo risultato. Da https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring_a_dependency_without_version :

Una pratica consigliata per i progetti più grandi è dichiarare le dipendenze senza versioni e utilizzare i vincoli di dipendenza per la dichiarazione della versione. Il vantaggio è che i vincoli di dipendenza consentono di gestire le versioni di tutte le dipendenze, comprese quelle transitive, in un'unica posizione.

Nel tuo build.gradlefile genitore :

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

Il wrapping del blocco delle dipendenze con un controllo per il plug-in Java (... whenPluginAdded {) non è strettamente necessario, ma gestirà quindi l'aggiunta di un progetto non Java alla stessa build.

Quindi in un progetto gradle per bambini puoi semplicemente omettere la versione:

apply plugin: "java"

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

Le build secondarie possono ancora scegliere di specificare una versione successiva. Se viene specificata una versione inferiore, viene automaticamente aggiornata alla versione nel vincolo.


1
I vincoli di dipendenza sono stati aggiunti in Gralde 4.6, quindi funziona con Gradle 4.6 o versioni successive.
Jim Hurne

Penso che Gradle preveda l' utilizzo del plug-in della piattaforma Java in questo caso. Tuttavia, la documentazione di Gradle non è molto chiara a questo punto. Immagino che anche l'uso di allprojectsvada bene.
JojOatXGME

voglio dichiarare i vincoli nel progetto root ma solo in uno dei miei sottoprogetti, voglio caricare tutte quelle dipendenze che hanno vincoli definiti.
dtc

2

io.spring.gradle:dependency-management-pluginplugin ha problemi con la nuova serie Gradle 3.x ma stabile per la serie 2.x. Per riferimento guarda al bug report Drop support per Gradle 3 # 115

In caso di Spring ( principale promotore dell'utilizzo della distinta base ) potresti concludere 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'
}

Nota che io.spring.platform:platform-bomha org.springframework.boot:spring-boot-starter-parentcome genitore quindi è compatibile con Spring Boot

È possibile verificare l'effettiva risoluzione delle dipendenze tramite:

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

$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ

o con compito:

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

Leggi il post del blog ufficiale di Soring Una migliore gestione delle dipendenze per Gradle per capire il motivo dell'introduzione io.spring.gradle:dependency-management-plugin.


1

Puoi centralizzare una dipendenza utilizzando il codice seguente:

Nel 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

In ogni modulo aggiungi 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}"
}


0

Per mantenere pulito il tuo file gradle, possiamo raggruppare le dipendenze in un array e implementarle in seguito.

  1. Aggiungi la versione di librerie come questa in build.gradle (a livello di app) al di fuori del blocco delle dipendenze :

// dichiara le versioni della libreria

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'
  1. Crea un array di dipendenze correlate, in modo da poterlo trovare facilmente in seguito. Aggiungilo in build.gradle (livello app) al di fuori del blocco delle dipendenze :

// Utilizzo della versione nella libreria e aggiunta di dipendenza insieme al nome di accesso (come retrofit (primo))

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. E nel blocco delle dipendenze :

// Implementa tutta la dipendenza dall'array

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

    implementation networkDependencies.values()
}

Quindi il codice finale sarà simile a questo:

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()
}

come includere il processore di annotazioni da questo ?? come nel caso di lombok
Pritish Joshi il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.