Jak wykluczyć wszystkie wystąpienia zależności przechodnich podczas korzystania z Gradle?

105

Mój projekt Gradle używa applicationwtyczki do zbudowania pliku jar. W ramach zależności przechodnich środowiska uruchomieniowego w końcu ściągam org.slf4j:slf4j-log4j12. (Jest to określane jako zależność przechodnia w co najmniej 5 lub 6 innych zależnościach przechodnich - ten projekt używa sprężyny i hadoopa, więc wszystko oprócz zlewu kuchennego jest wciągane ... nie czekaj ... to też jest :) ).

Chcę globalnie wykluczyć slf4j-log4j12słoik z mojego zbudowanego słoika. Więc próbowałem tego:

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

Wydaje się jednak, że wyklucza to wszystkie org.slf4j artefakty, w tym slf4j-api. Podczas pracy w trybie debugowania widzę linie takie jak:

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).

Nie chcę wyszukiwać źródła każdej slf4j-log4j12zależności przechodniej, a następnie umieszczać compile foo { exclude slf4j... }w dependenciesbloku poszczególne instrukcje .

Aktualizacja:

Próbowałem też tego:

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

Co kończy się wykluczeniem wszystkiego z kompilacji! Jakbym sprecyzował group: "*".

Aktualizacja 2:

Używam do tego Gradle w wersji 1.10.

Jens D.
źródło
2
możesz chcieć przyjąć odpowiedzi na swoje pytania; jest uprzejmy i wzbudza większe zainteresowanie odpowiadaniem na twoje pytania
Michael Deardeuff

Odpowiedzi:

139

Ach, poniższe działa i robi to, co chcę:

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

Wygląda na to, że reguła wykluczania ma tylko dwa atrybuty - groupi module. Jednak powyższa składnia nie zapobiega określaniu dowolnej właściwości jako predykatu. Podczas próby wykluczenia z indywidualnej zależności nie można określić dowolnych właściwości. Na przykład to się nie udaje:

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

z

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

Więc nawet jeśli możesz określić zależność za pomocą a group:i name:nie możesz określić wykluczenia za pomocą name:!?!

Może osobne pytanie, ale czym właściwie jest moduł ? Rozumiem pojęcie groupId: artifactId: wersja w Mavenie, co, jak rozumiem, przekłada się na grupę: nazwa: wersja w Gradle. Ale skąd mam wiedzieć, do jakiego modułu (mówiąc językiem stopniowym) należy dany artefakt Mavena?

Jens D.
źródło
1
Wydaje się, że jest to lepsza dyskusja na forach Gradle .
superEb
Tak zrobione - forums.gradle.org/gradle/topics/ ...
Jens D
3
Ugh, właśnie zmagałem się z tym konkretnym problemem. Wydaje mi się, że wyjątkowo trudno jest cokolwiek zrobić za pomocą gradle, zwłaszcza rozwiązywać konflikty w dużym projekcie. Z radością wziąłbym rozwlekły xml z walidacją xsd zamiast gradle's dsl
cjbooms
Pole „name:” powinno mieć wartość „module:”, wtedy będzie działać dla u :)
GuyK
1
Z korzyścią dla mnie i innych w przyszłości chciałem wykluczyć WSZYSTKIE biblioteki zależności (Gradle 3.3) z mojego pakietu wojennego. Więc zamiast wymieniać każdy z nich, po prostu zrobiłem configurations { runtime.exclude group: '*' }.
user1070304
39

Aby wykluczyć jedną lub więcej bibliotek globalnie, dodaj następujący kod do pliku build.gradle

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

Teraz blok wykluczający ma dwie właściwości, grupę i moduł . Dla tych z Was, którzy pochodzą z maven background, group jest taka sama jak groupId, a module jest taka sama jak artifactId . Przykład: Aby wykluczyć com.mchange: c3p0: 0.9.2.1, należy dodać blok wykluczający

exclude group:"com.mchange", module:"c3p0"
Venom.unleashed
źródło
1
dzięki, rozumiem, mogli powiedzieć, że moduł oznacza nazwę
Remario
29

Twoje podejście jest prawidłowe. (W zależności od okoliczności, możesz chcieć użyć configurations.all { exclude ... }.) Jeśli te wykluczenia naprawdę wykluczają więcej niż jedną zależność (nigdy nie zauważyłem tego podczas ich używania), zgłoś błąd na http://forums.gradle.org najlepiej z powtarzalnym przykładem.

Peter Niederwieser
źródło
1
configurations.all{}jest dokładnie tym, czego szukałem. Dzięki za post Piotr
pczeus
21

w poniższym przykładzie wykluczam

spring-boot-starter-tomcat

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
źródło
5

Używałem spring boot 1.5.10 i próbuję wykluczyć logback, powyższe rozwiązanie nie działało dobrze, zamiast tego używam konfiguracji

configurations.all {
    exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
}
mark ortiz
źródło
3

Oprócz tego, co powiedział @ berguiga-mohamed-amine, właśnie odkryłem, że symbol wieloznaczny wymaga pozostawienia argumentu modułu pustego ciągu:

compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") {
    exclude group: 'org.apache.httpcomponents', module: ''
    exclude group: 'org.slf4j', module: ''
}
Arnold Schrijver
źródło