Bagaimana cara mengecualikan semua instance dependensi transitif saat menggunakan Gradle?

104

Proyek gradle saya menggunakan applicationplugin untuk membuat file jar. Sebagai bagian dari dependensi transitif runtime, saya akhirnya berhenti org.slf4j:slf4j-log4j12. (Ini direferensikan sebagai ketergantungan sub-transitif di setidaknya 5 atau 6 dependensi transitif lainnya - proyek ini menggunakan pegas dan hadoop, jadi semuanya kecuali wastafel dapur ditarik masuk ... tidak tunggu ... itu juga ada :) ).

Saya ingin mengecualikan slf4j-log4j12toples secara global dari toples buatan saya. Jadi saya sudah mencoba ini:

configurations {
  runtime.exclude group: "org.slf4j", name: "slf4j-log4j12"
}

Namun, ini tampaknya mengecualikan semua org.slf4j artefak termasuk slf4j-api. Saat menjalankan mode debug saya melihat baris seperti:

org.slf4j#slf4j-api is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-simple is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-log4j12 is excluded from org.apache.hadoop:hadoop-common:2.2.0(runtime).

Saya tidak ingin mencari sumber dari setiap slf4j-log4j12ketergantungan transitif dan kemudian memiliki compile foo { exclude slf4j... }pernyataan individu di dependenciesblok saya .

Memperbarui:

Saya juga mencoba ini:

configurations {
  runtime.exclude name: "slf4j-log4j12"
}

Yang akhirnya tidak termasuk semuanya dari build! Seolah-olah saya tentukan group: "*".

Perbarui 2:

Saya menggunakan Gradle versi 1.10 untuk ini.

Jens D
sumber
2
Anda mungkin ingin menerima jawaban atas pertanyaan Anda; itu sopan dan menarik lebih banyak minat dalam menjawab pertanyaan Anda
Michael Deardeuff

Jawaban:

136

Ah, berikut ini berhasil dan melakukan apa yang saya inginkan:

configurations {
  runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
}

Tampaknya Aturan Pengecualian hanya memiliki dua atribut - groupdan module. Namun, sintaks di atas tidak mencegah Anda menentukan properti arbitrer apa pun sebagai predikat. Saat mencoba mengecualikan dari dependensi individu, Anda tidak dapat menentukan properti arbitrer. Misalnya, ini gagal:

dependencies {
  compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
    exclude group: "org.slf4j", name: "slf4j-log4j12"
  }
}

dengan

No such property: name for class: org.gradle.api.internal.artifacts.DefaultExcludeRule

Jadi meskipun Anda bisa menentukan ketergantungan dengan a group:dan name:Anda tidak bisa menentukan pengecualian dengan name:!?!

Mungkin pertanyaan yang terpisah, tapi apa sebenarnya adalah modul kemudian? Saya bisa memahami gagasan Maven tentang groupId: artifactId: version, yang saya pahami diterjemahkan menjadi group: name: version di Gradle. Tapi kemudian, bagaimana saya tahu modul apa (dalam bahasa gradle) milik artefak Maven tertentu?

Jens D
sumber
1
Ini sepertinya diskusi yang lebih baik untuk forum Gradle .
superEb
3
Ugh, saya baru saja berjuang dengan masalah ini. Saya merasa sangat sulit untuk melakukan apa pun dengan gradle, terutama menyelesaikan konflik pada proyek besar. Saya akan dengan senang hati mengambil verbose xml dengan validasi xsd atas dsl
gradle
"Name:" harus "module:", maka itu akan bekerja untuk Anda :)
GuyK
1
Untuk kepentingan saya di masa mendatang dan orang lain, saya ingin mengecualikan SEMUA perpustakaan dependensi (Gradle 3.3) dari paket perang saya. Jadi, daripada mencantumkan masing-masing, saya hanya melakukannya configurations { runtime.exclude group: '*' }.
pengguna1070304
39

Untuk mengecualikan satu atau beberapa library secara global, tambahkan berikut ini ke build.gradle Anda

configurations.all {
   exclude group:"org.apache.geronimo.specs", module: "geronimo-servlet_2.5_spec"
   exclude group:"ch.qos.logback", module:"logback-core"
}

Sekarang blok pengecualian memiliki dua grup properti dan modul . Bagi Anda yang berasal dari latar belakang maven, grup sama dengan groupId dan modul sama dengan artifactId . Contoh: Untuk mengecualikan com.mchange: c3p0: 0.9.2.1 berikut harus mengecualikan blok

exclude group:"com.mchange", module:"c3p0"
venom.unleashed
sumber
1
terima kasih saya mengerti, mereka bisa mengatakan nama modul berarti
Remario
29

Pendekatan Anda benar. (Bergantung pada situasinya, Anda mungkin ingin menggunakan configurations.all { exclude ... }.) Jika pengecualian ini benar-benar mengecualikan lebih dari satu ketergantungan (saya belum pernah memperhatikannya saat menggunakannya), laporkan bug di http://forums.gradle.org , idealnya dengan contoh yang dapat direproduksi.

Peter Niederwieser
sumber
1
configurations.all{}persis seperti yang saya cari. Terima kasih atas kiriman Peter
pczeus
20

pada contoh di bawah ini saya kecualikan

musim semi-boot-starter-kucing jantan

compile("org.springframework.boot:spring-boot-starter-web") {
     //by both name and group
     exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' 
}
BERGUIGA Mohamed Amine
sumber
5

Saya menggunakan spring boot 1.5.10 dan mencoba mengecualikan logback, solusi yang diberikan di atas tidak berfungsi dengan baik, saya menggunakan konfigurasi sebagai gantinya

configurations.all {
    exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
}
tandai ortiz
sumber
3

Selain apa yang dinyatakan @ berguiga-mohamed-amine, saya baru saja menemukan bahwa wildcard mengharuskan argumen modul meninggalkan string kosong:

compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") {
    exclude group: 'org.apache.httpcomponents', module: ''
    exclude group: 'org.slf4j', module: ''
}
Arnold Schrijver
sumber