W Gradle, jak zadeklarować wspólne zależności w jednym miejscu?

109

W Maven jest bardzo przydatna funkcja, gdy można zdefiniować zależność w <dependencyManagement>sekcji nadrzędnego POM i odwołać się do tej zależności z modułów potomnych bez określania wersji, zakresu lub czegokolwiek.

Jakie są alternatywy w Gradle?

Stanislav Bashkyrtsev
źródło

Odpowiedzi:

179

Możesz zadeklarować typowe zależności w skrypcie nadrzędnym:

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

Ze skryptu podrzędnego możesz następnie użyć deklaracji zależności w następujący sposób:

dependencies {
    compile libraries.spring_core
    testCompile libraries.junit
}

Aby udostępnić deklaracje zależności z zaawansowanymi opcjami konfiguracji, możesz użyć DependencyHandler.create:

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

Wiele zależności można udostępniać pod tą samą nazwą:

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

dependencies { compile libraries.spring } doda wtedy obie zależności jednocześnie.

Jedyną informacją, której nie możesz udostępniać w ten sposób, jest to, do jakiej konfiguracji ( zakresu w terminologii Maven) należy przypisać zależność. Jednak z mojego doświadczenia wynika, że ​​i tak lepiej jest o tym powiedzieć.

Peter Niederwieser
źródło
3
Dzięki, to rozwiązuje moje pytanie, ale nadal mam obawy. W Maven możemy pozostawić wersję pustą, a jeśli jest to biblioteka, jest to wygodne, ponieważ można jej użyć w naszej aplikacji i wprowadzić dependencyManagement, aby zdefiniować wersję biblioteki to powinno zająć. Jak byś zrobił to samo z Gradle?
Stanislav Bashkyrtsev
Nie rozumiem pytania. Proszę podać przykład.
Peter Niederwieser
4
Peter, ctapobep mówi, że w maven możesz zadeklarować zależności z wersją (i zakresem) w pom rodzica (lub agregatora) w sekcji dependencyManagement. Następnie w pompie „konkretnym” nie musisz ponownie deklarować wersji; po prostu artefact i groupId. Zasadniczo mówi mavenowi „Potrzebuję X: Y, ale użyj dowolnej wersji skonfigurowanej przez rodzica”.
Michael Campbell
2
Aby uniknąć tego rodzaju duplikacji, staram się tworzyć osobny dependencies.gradleskrypt, w którym wszystkie moje zależności definiuję jako właściwości, np ext.GROOVY = 'org.codehaus.groovy:groovy-all:2.1.6'. : . W ramach projektu głównego build.gradle, to ja allprojects { apply from: "$rootDir/dependencies.gradle" }. Wtedy wszystkie zależności są definiowane w jednym pliku, zamiast je rozpraszać, a więcej „łatwych do odczytania” stałych jest używanych w konfiguracjach zależności.
Steinar
1
Dokładnie to zrobiłem powyżej. Nie musisz składać wniosku, allprojectsponieważ dodatkowe właściwości na poziomie projektu są widoczne dla podprojektów.
Peter Niederwieser
7

To późna odpowiedź, ale możesz również zajrzeć na: http://plugins.gradle.org/plugin/io.spring.dependency-management Zapewnia możliwość zaimportowania „bom” producenta i ponownego wykorzystania definicji zdefiniowane w „bom”. Z pewnością jest to dobra pomoc przy stopniowej migracji z maven do gradle! Cieszę się tym teraz.

pokojeg
źródło
jest to nawet niezbędne, gdy chcesz udostępniać te same zależności w kilku (wielu) projektach.
pokojeg
7
Chociaż jest wygodna, ta wtyczka może mieć znaczący wpływ na wydajność. W przypadku 30 podprojektów z ponad 200 zależnościami dodaje to 1 minutę do fazy rozwiązywania zależności. W przypadku małych projektów działa to jednak jak urok
Jk1
zastępuje również przechodnie wersje zależności, powiedzmy, że zadeklarowałeś wersję 3.0.0 w zarządzaniu zależnościami, ale dla jednego z podprojektów musisz użyć starszej wersji, np. 2.5.0, wtedy jeśli masz projekt zależny od tego starszego projektu, zależność przechodnia zostanie nadpisana z 2.5.0 na to, co zadeklarowano we wtyczce zarządzania zależnościami, więc 3.0.0 w tym przypadku bardzo dziwne zachowanie
KameeCoding
7

Począwszy od Gradle 4.6, ograniczenia zależności są sugerowane w dokumentacji jako sposób osiągnięcia tego. Z https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring_a_dependency_without_version :

Zalecaną praktyką w przypadku większych projektów jest deklarowanie zależności bez wersji i używanie ograniczeń zależności do deklarowania wersji. Zaletą jest to, że ograniczenia zależności umożliwiają zarządzanie wersjami wszystkich zależności, w tym przechodnimi, w jednym miejscu.

W build.gradlepliku nadrzędnym :

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

Opakowywanie bloku zależności za pomocą sprawdzenia wtyczki Java (... whenPluginAdded {) nie jest bezwzględnie konieczne, ale będzie wtedy obsługiwać dodawanie projektu innego niż Java do tej samej kompilacji.

Następnie w projekcie oceny podrzędnej możesz po prostu pominąć wersję:

apply plugin: "java"

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

Kompilacje podrzędne nadal mogą określać wyższą wersję. Jeśli określono niższą wersję, jest ona automatycznie uaktualniana do wersji w ograniczeniu.

Adrian Baker
źródło
1
Ograniczenia zależności zostały dodane w Gralde 4.6, więc będzie działać z Gradle 4.6 lub nowszym.
Jim Hurne,
Myślę, że Gradle zapewnia, że w takim przypadku używana jest wtyczka platformy Java . Jednak dokumentacja Gradle nie jest w tym momencie zbyt jasna. Myślę, że użycie allprojectsjest również w porządku.
JojOatXGME
chcę zadeklarować ograniczenia w projekcie głównym, ale tylko w jednym z moich podprojektów, chcę załadować wszystkie te zależności, które mają zdefiniowane ograniczenia.
dtc
2

io.spring.gradle:dependency-management-pluginwtyczka ma problemy z nową serią Gradle 3.x, ale stabilna dla serii 2.x. W celach informacyjnych zajrzyj do raportu o błędzie Porzuć wsparcie dla Gradle 3 # 115

W przypadku Spring ( główny promotor wykorzystania BOM ) możesz zakończyć:

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'
}

Zauważ, że io.spring.platform:platform-bomma org.springframework.boot:spring-boot-starter-parentjako rodzica, więc jest kompatybilny z Spring Boot

Rzeczywiste rozwiązanie zależności można zweryfikować poprzez:

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

$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ

lub z zadaniem:

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

Przeczytaj oficjalny wpis na blogu Soring Lepsze zarządzanie zależnościami dla Gradle, aby zrozumieć powód wprowadzenia io.spring.gradle:dependency-management-plugin.

gavenkoa
źródło
1

Możesz scentralizować zależność za pomocą poniższego kodu:

W 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

W każdym module dodaj do 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
źródło
1

Ten post na blogu sugeruje zarządzanie zależnościami i grupami jako konfiguracjami: https://www.javacodegeeks.com/2016/05/manage-dependencies-gradle-multi-project-build.html

Sam tego nie próbowałem, ale wygląda ciekawie.

Projekt główny build.gradle

subprojects {
  configurations {
    commonsIo
  }

  dependencies {
    commonsIo 'commons-io:commons-io:2.5'
  }
}

Podprojekt build.gradle

configurations {
  compile.extendsFrom commonsIo
}
tkruse
źródło
0

Aby zachować porządek w pliku, możemy zgrupować zależności w tablicy i zaimplementować je później.

  1. Dodaj wersję bibliotek taką jak ta w build.gradle (poziom aplikacji) poza blokiem zależności :

// deklaruj wersje biblioteki

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'
  1. Utwórz tablicę powiązanych zależności, aby móc ją później łatwo znaleźć. Dodaj go w build.gradle (poziom aplikacji) poza blokiem zależności :

// Używanie wersji w bibliotece i dodawanie zależności wraz z nazwą dostępu (np. Retrofit (pierwszy))

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. A w bloku zależności :

// Zaimplementuj wszystkie zależności z tablicy

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

    implementation networkDependencies.values()
}

Więc ostateczny kod będzie wyglądał następująco:

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
źródło
jak dołączyć przez to procesor adnotacji? jak w przypadku
lomboka