¿Cómo excluyo todas las instancias de una dependencia transitiva cuando uso Gradle?

Mi proyecto gradle utiliza el complemento de la application para crear un archivo jar. Como parte de las dependencias transitivas de tiempo de ejecución, termino tirando de org.slf4j:slf4j-log4j12 . (Se lo menciona como una dependencia sub-transitiva en al menos 5 u 6 dependencias transitivas adicionales; este proyecto utiliza la spring y hadoop, por lo que todo lo que no sea el fregadero de la cocina se detiene … no, espera … eso también está ahí 🙂 )

Quiero excluir globalmente el slf4j-log4j12 de mi jar construido. Así que he intentado esto:

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

Sin embargo, esto parece excluir todos los artefactos org.slf4j , incluido slf4j-api . Cuando se ejecuta en modo de depuración veo líneas 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). 

No quiero tener que buscar el origen de cada dependencia transitiva slf4j-log4j12 y luego tener compile foo { exclude slf4j... } individuales compile foo { exclude slf4j... } en mi bloque de dependencies .

Actualizar:

Yo también probé esto:

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

¡Lo cual termina excluyendo todo de la construcción! Como si hubiera especificado un group: "*" .

Actualización 2:

Estoy usando la versión 1.10 de Gradle para esto.

Ah, el siguiente funciona y hace lo que quiero:

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

Parece que una regla de exclusión solo tiene dos atributos: group y module . Sin embargo, la syntax anterior no le impide especificar cualquier propiedad arbitraria como un predicado. Al intentar excluir de una dependencia individual, no puede especificar propiedades arbitrarias. Por ejemplo, esto falla:

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

con

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

Entonces, aunque puede especificar una dependencia con un group: y name: no puede especificar una exclusión con un name: !?!

Quizás una pregunta separada, pero ¿ qué es exactamente un módulo entonces? Puedo entender la noción de Maven de groupId: artifactId: version, que entiendo se traduce a group: name: version en Gradle. Pero entonces, ¿cómo sé qué módulo (en gradle-speak) pertenece a un artefacto Maven particular?

Tu enfoque es correcto. (Dependiendo de las circunstancias, es posible que desee utilizar configurations.all { exclude ... } .) Si estas exclusiones realmente excluyen más de una dependencia (no lo he notado al usarlas), presente un error en http://forums.gradle.org , idealmente con un ejemplo reproducible.

Para excluir una o más bibliotecas globalmente, agregue lo siguiente a su build.gradle

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

Ahora el bloque exclude tiene dos propiedades grupo y módulo . Para aquellos de ustedes que provienen de maven background, group es lo mismo que groupId y module es lo mismo que artifactId . Ejemplo: excluir com.mchange: c3p0: 0.9.2.1 siguiente debe excluirse bloque

 exclude group:"com.mchange", module:"c3p0" 

en el ejemplo abajo, excluyo

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

Estaba usando el arranque de spring 1.5.10 e bash excluir el logback, la solución anterior no funcionó bien, utilizo configuraciones en su lugar

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