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

104

Mi proyecto gradle usa el applicationcomplemento para crear un archivo jar. Como parte de las dependencias transitivas del tiempo de ejecución, termino entrando org.slf4j:slf4j-log4j12. (Se hace referencia a ella como una dependencia sub-transitiva en al menos 5 o 6 otras dependencias transitivas; este proyecto está usando spring y hadoop, por lo que todo, excepto el fregadero de la cocina, se está tirando ... no, espera ... eso también está ahí :) ).

Quiero excluir globalmente el slf4j-log4j12jar de mi jar construido. Entonces probé esto:

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

Sin embargo, esto parece excluir todos los org.slf4j artefactos incluidos 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 la fuente de cada slf4j-log4j12dependencia transitiva y luego tener compile foo { exclude slf4j... }declaraciones individuales en mi dependenciesbloque.

Actualizar:

También probé esto:

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

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

Actualización 2:

Estoy usando Gradle versión 1.10 para esto.

Jens D
fuente
2
es posible que desee aceptar respuestas a sus preguntas; es educado y genera más interés en responder a sus preguntas
Michael Deardeuff

Respuestas:

137

Ah, lo 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: groupy module. Sin embargo, la sintaxis anterior no le impide especificar ninguna propiedad arbitraria como 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 a group:y name:no puede especificar una exclusión con a 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 en group: name: version en Gradle. Pero entonces, ¿cómo sé a qué módulo (en lenguaje gradle) pertenece un artefacto Maven en particular?

Jens D
fuente
1
Esto parece una mejor discusión para los foros de Gradle .
magnífico
3
Uf, solo luché con este problema exacto. Me resulta excepcionalmente difícil hacer algo con gradle, especialmente resolver conflictos en un proyecto grande. Felizmente tomaría xml detallado con validación xsd sobre dsl de
gradle
El "nombre:" debería ser "módulo:", entonces funcionará para
ti
1
Para el beneficio de otros y yo en el futuro, quería excluir TODAS las bibliotecas de dependencia (Gradle 3.3) de mi paquete de guerra. Entonces, en lugar de enumerar cada uno, simplemente lo hice configurations { runtime.exclude group: '*' }.
user1070304
39

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 de exclusión tiene dos grupos de propiedades y un módulo . Para aquellos de ustedes que vienen de la experiencia de Maven , el grupo es el mismo que el ID de grupo y el módulo es el mismo que el ID de artefacto . Ejemplo: Para excluir com.mchange: c3p0: 0.9.2.1 lo siguiente debe ser bloque de exclusión

exclude group:"com.mchange", module:"c3p0"
veneno desatado
fuente
1
gracias, entiendo, podrían haber dicho módulo significa nombre
Remario
29

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 (nunca me he dado cuenta de eso al usarlas), presente un error en http://forums.gradle.org , idealmente con un ejemplo reproducible.

Peter Niederwieser
fuente
1
configurations.all{}es exactamente lo que estaba buscando. Gracias por la publicación Peter
pczeus
20

en el siguiente ejemplo excluyo

primavera-arranque-arrancador-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
fuente
5

Estaba usando Spring Boot 1.5.10 e intento excluir el logback, la solución dada arriba no funcionó bien, en su lugar uso configuraciones

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

Además de lo que dijo @ berguiga-mohamed-amine, acabo de descubrir que un comodín requiere dejar el argumento del módulo como una cadena vacía:

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