Di Gradle, bagaimana cara mendeklarasikan dependensi umum di satu tempat?

109

Di Maven terdapat fitur yang sangat berguna ketika Anda dapat menentukan dependensi di <dependencyManagement>bagian POM induk, dan mereferensikan dependensi tersebut dari modul turunan tanpa menentukan versi atau cakupan atau apa pun.

Apa alternatif di Gradle?

Stanislav Bashkyrtsev
sumber

Jawaban:

179

Anda dapat mendeklarasikan dependensi umum dalam skrip induk:

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

Dari skrip anak, Anda kemudian dapat menggunakan deklarasi dependensi seperti ini:

dependencies {
    compile libraries.spring_core
    testCompile libraries.junit
}

Untuk membagikan deklarasi dependensi dengan opsi konfigurasi lanjutan, Anda dapat menggunakan DependencyHandler.create:

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

Beberapa dependensi dapat dibagikan dengan nama yang sama:

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

dependencies { compile libraries.spring } kemudian akan menambahkan kedua dependensi sekaligus.

Satu bagian informasi yang tidak dapat Anda bagikan dengan cara ini adalah konfigurasi apa ( cakupan dalam istilah Maven) yang harus ditetapkan untuk dependensi. Namun, dari pengalaman saya, lebih baik menjelaskan hal ini secara eksplisit.

Peter Niederwieser
sumber
3
Terima kasih, ini menjawab pertanyaan saya, tetapi masih ada kekhawatiran .. Di Maven kita dapat membiarkan versinya kosong dan jika ini adalah lib, akan lebih mudah karena Anda dapat menggunakannya di aplikasi kita dan membuat dependencyManagement untuk menentukan versi lib apa itu harus mengambil. Bagaimana Anda melakukan hal yang sama dengan Gradle?
Stanislav Bashkyrtsev
Saya tidak mengerti pertanyaannya. Berikan contoh.
Peter Niederwieser
4
Peter, apa yang dikatakan ctapobep adalah bahwa di maven Anda dapat mendeklarasikan dependensi dengan versi (dan cakupan) di pom induk (atau aggregator) di bagian dependencyManagement. Kemudian di pom "beton", Anda tidak perlu mendeklarasikan ulang versinya; hanya artefak dan groupId. Pada dasarnya ini memberi tahu maven "Saya butuh X: Y, tetapi gunakan versi apa pun yang telah dikonfigurasi orang tua."
Michael Campbell
2
Untuk menghindari semacam ini duplikasi, saya cenderung untuk membuat terpisah dependencies.gradlenaskah mana saya mendefinisikan semua dependensi saya sebagai properti, misalnya: ext.GROOVY = 'org.codehaus.groovy:groovy-all:2.1.6'. Dalam proyek root build.gradle, saya menyertakan allprojects { apply from: "$rootDir/dependencies.gradle" }. Kemudian semua dependensi didefinisikan dalam satu file alih-alih menyebarkannya, dan lebih banyak konstanta yang "mudah dibaca" digunakan dalam konfigurasi dependensi.
Steinar
1
Itulah yang saya lakukan di atas. Anda tidak perlu mendaftar allprojectskarena properti tambahan tingkat proyek dapat dilihat oleh subproyek.
Peter Niederwieser
7

Ini adalah balasan yang terlambat, namun Anda mungkin juga ingin melihat: http://plugins.gradle.org/plugin/io.spring.dependency-management Ini memberikan kemungkinan untuk mengimpor 'bom' pakar, dan menggunakan kembali definisi didefinisikan dalam 'bom'. Ini tentunya sangat membantu ketika secara bertahap bermigrasi dari maven ke gradle! Menikmatinya sekarang.

kamar
sumber
bahkan harus dimiliki saat Anda ingin berbagi dependensi yang sama di beberapa (multi) project.
roomsg
7
Meskipun nyaman, plugin ini mungkin memiliki jejak kinerja yang signifikan. Untuk 30 subproyek dengan 200+ dependensi, ini menambahkan hingga 1 menit ke fase resolusi dependensi. Untuk proyek kecil, ini bekerja seperti pesona
Jk1
itu juga menggantikan versi ketergantungan transitif, katakanlah Anda telah menyatakan versi 3.0.0 dalam manajemen ketergantungan, tetapi untuk salah satu subproyek Anda perlu menggunakan versi yang lebih lama misalnya 2.5.0, maka jika Anda memiliki proyek yang bergantung pada proyek lama ini, ketergantungan transitif akan ditimpa dari 2.5.0 ke apa yang dideklarasikan dalam plugin manajemen ketergantungan jadi 3.0.0 dalam hal ini adalah perilaku yang sangat aneh
KameeCoding
7

Mulai Gradle 4.6, batasan dependensi disarankan dalam dokumentasi sebagai cara untuk mencapainya. Dari https://docs.gradle.org/current/userguide/declaring_dependencies.html#declaring_a_dependency_without_version :

Praktik yang direkomendasikan untuk project yang lebih besar adalah mendeklarasikan dependensi tanpa versi dan menggunakan batasan dependensi untuk deklarasi versi. Keuntungannya adalah batasan dependensi memungkinkan Anda mengelola versi semua dependensi, termasuk yang transitif, di satu tempat.

Di build.gradlefile induk Anda :

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

Membungkus blok dependensi dengan pemeriksaan plugin Java (... whenPluginAdded {) tidak sepenuhnya diperlukan, tetapi kemudian akan menangani penambahan proyek non-Java ke build yang sama.

Kemudian dalam proyek gradle anak Anda cukup menghilangkan verison:

apply plugin: "java"

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

Build anak masih dapat memilih untuk menentukan versi yang lebih tinggi. Jika versi yang lebih rendah ditentukan, itu secara otomatis ditingkatkan ke versi dalam batasan.

Adrian Baker
sumber
1
Batasan dependensi ditambahkan di Gralde 4.6, jadi ini akan berfungsi dengan Gradle 4.6 atau yang lebih tinggi.
Jim Hurne
Saya rasa Gradle menyatakan bahwa Java Platform Plugin digunakan dalam kasus seperti itu. Namun, dokumentasi Gradle tidak terlalu jelas saat ini. Saya kira penggunaan allprojectsjuga baik-baik saja.
JojOatXGME
saya ingin mendeklarasikan batasan dalam proyek root tetapi hanya di salah satu subproyek saya, saya ingin memuat semua dependensi yang memiliki batasan yang ditentukan.
dtc
2

io.spring.gradle:dependency-management-pluginplugin memiliki masalah dengan seri Gradle 3.x baru tetapi stabil untuk seri 2.x. Untuk referensi, lihat laporan bug Dukungan Drop untuk Gradle 3 # 115

Dalam kasus Spring ( promotor utama penggunaan BOM ), Anda dapat mengakhiri dengan:

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

Perhatikan bahwa io.spring.platform:platform-bommiliki org.springframework.boot:spring-boot-starter-parentsebagai orang tua sehingga cocok dengan Spring Boot

Anda dapat memverifikasi resolusi ketergantungan aktual melalui:

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

$ gradle buildEnvironment
$ gradle buildEnvironment -p $SUBPROJ

atau dengan tugas:

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

Baca entri blog resmi Soring Manajemen ketergantungan yang lebih baik untuk Gradle untuk memahami alasan pengenalan io.spring.gradle:dependency-management-plugin.

gavenkoa.dll
sumber
1

Anda dapat memusatkan ketergantungan menggunakan kode di bawah ini:

Di 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

Di setiap modul tambahkan ke 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
sumber
1

Entri blog ini menyarankan pengelolaan dependensi dan grup sebagai konfigurasi: https://www.javacodegeeks.com/2016/05/manage-dependencies-gradle-multi-project-build.html

Saya belum mencobanya sendiri, tapi kelihatannya menarik.

Proyek root build.gradle

subprojects {
  configurations {
    commonsIo
  }

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

Subproyek build.gradle

configurations {
  compile.extendsFrom commonsIo
}
tkruse
sumber
0

Untuk menjaga agar file gradle Anda tetap bersih, kita bisa mengelompokkan ketergantungan dalam sebuah array dan mengimplementasikannya nanti.

  1. Tambahkan versi pustaka seperti ini di build.gradle (level aplikasi) di luar blok dependensi :

// deklarasikan versi pustaka

final RetrofitVersion = '2.3.0'
final OkHttpVersion = '3.9.1'
  1. Buat larik dependensi terkait, sehingga Anda dapat menemukannya dengan mudah nanti. Tambahkan di build.gradle (level aplikasi) di luar blok dependensi :

// Menggunakan versi di perpustakaan dan menambahkan ketergantungan bersama dengan nama akses (seperti retrofit (yang pertama))

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. Dan di blok ketergantungan :

// Implementasikan semua ketergantungan dari array

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

    implementation networkDependencies.values()
}

Jadi kode terakhirnya akan terlihat seperti ini:

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
sumber
bagaimana cara memasukkan pemroses anotasi dengan ini ?? seperti dalam kasus lombok
Pritish Joshi