Como excluo todas as instâncias de uma dependência transitiva ao usar o Gradle?

104

Meu projeto gradle usa o applicationplugin para construir um arquivo jar. Como parte das dependências transitivas do tempo de execução, eu acabo puxando org.slf4j:slf4j-log4j12. (É referenciado como uma dependência subtransitiva em pelo menos 5 ou 6 outras dependências transitivas - este projeto está usando spring e hadoop, então tudo, exceto a pia da cozinha está sendo puxado ... não espere ... isso também está lá :) )

Quero excluir globalmente o slf4j-log4j12jarro do meu jarro construído. Então, eu tentei isso:

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

No entanto, isso parece excluir todos os org.slf4j artefatos, incluindo slf4j-api. Ao executar no modo de depuração, vejo linhas como:

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

Não quero ter que pesquisar a origem de cada slf4j-log4j12dependência transitiva e, em seguida, ter compile foo { exclude slf4j... }instruções individuais em meu dependenciesbloco.

Atualizar:

Eu também tentei isso:

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

O que acaba excluindo tudo do build! Como se eu especificasse group: "*".

Atualização 2:

Estou usando o Gradle versão 1.10 para isso.

Jens D
fonte
2
você pode aceitar respostas às suas perguntas; é educado e atrai mais interesse em responder às suas perguntas
Michael Deardeuff,

Respostas:

136

Ah, o seguinte funciona e faz o que eu quero:

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

Parece que uma regra de exclusão tem apenas dois atributos - groupe module. No entanto, a sintaxe acima não impede que você especifique qualquer propriedade arbitrária como um predicado. Ao tentar excluir de uma dependência individual, você não pode especificar propriedades arbitrárias. Por exemplo, isso falha:

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

com

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

Portanto, embora você possa especificar uma dependência com um group:e name:não possa especificar uma exclusão com um name:!?!

Talvez uma pergunta separada, mas o que exatamente é um módulo então? Eu posso entender a noção Maven de groupId: artifactId: version, que eu entendo que se traduz em group: name: version no Gradle. Mas então, como posso saber a qual módulo (na linguagem gradle) um determinado artefato Maven pertence?

Jens D
fonte
1
Esta parece ser uma discussão melhor para os fóruns do Gradle .
superEb
Então feito - forums.gradle.org/gradle/topics/…
Jens D
3
Ugh, eu apenas lutei exatamente com esse problema. Acho extremamente difícil fazer qualquer coisa com o Gradle, especialmente resolver conflitos em um grande projeto. Eu ficaria feliz em obter xml detalhado com validação xsd em vez do dsl do
gradle
O "nome:" deve ser "módulo:", então funcionará para você :)
GuyK
1
Para o benefício de mim e de outros no futuro, eu queria excluir TODAS as bibliotecas de dependência (Gradle 3.3) do meu pacote war. Então, ao invés de listar cada um, eu simplesmente fiz configurations { runtime.exclude group: '*' }.
user1070304
39

Para excluir uma ou mais bibliotecas globalmente, adicione o seguinte ao seu build.gradle

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

Agora, o bloco de exclusão possui dois grupos e módulos de propriedades . Para aqueles que têm experiência com o maven, group é igual a groupId e module é igual a artifactId . Exemplo: Para excluir com.mchange: c3p0: 0.9.2.1 o seguinte deve ser exclude block

exclude group:"com.mchange", module:"c3p0"
venom.unleashed
fonte
1
obrigado, eu entendo, eles poderiam ter dito módulo significa nome
Remario
29

Sua abordagem está correta. (Dependendo das circunstâncias, você pode querer usar configurations.all { exclude ... }.) Se essas exclusões realmente excluem mais de uma única dependência (nunca percebi isso ao usá-las), registre um bug em http://forums.gradle.org , de preferência com um exemplo reproduzível.

Peter Niederwieser
fonte
1
configurations.all{}é exatamente o que eu estava procurando. Obrigado pela postagem Peter
pczeus
20

no exemplo abaixo eu excluo

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
fonte
5

Eu estava usando o spring boot 1.5.10 e tento excluir o logback, a solução fornecida acima não funcionou bem, eu uso configurações em vez disso

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

Além do que @ berguiga-mohamed-amine afirmou, acabei de descobrir que um caractere curinga exige que o argumento do módulo seja deixado com a string vazia:

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