2012-03-29 13 views
17

Usando Gradle 1,0 hito 8.Gradle - excluir una dependencia de una configuración, pero no para una configuración de heredar

Mi proyecto utiliza slf4j + Logback para el registro, por lo que quiero evitar cualquier deps transitivos en log4j de contaminar mi classpath. Por lo tanto, he añadido una exclusión global, de este modo:

configurations { 
    all*.exclude group: "log4j", module: "log4j" 
} 

Sin embargo, estoy usando una biblioteca de prueba (hadoop-minicluster), que tiene una dependencia de tiempo de ejecución de log4j, por lo que ahora tengo que permitir que una dependencia log4j para mi tiempo de ejecución de pruebas . He intentado añadir una dependencia directa de log4j:

testRuntime group: "log4j", name: "log4j", version: "1.2.15" 

y editar mi código de exclusión (un poco de un truco):

configurations.findAll {!it.name.endsWith('testRuntime')}.each { conf -> 
    conf.exclude group: "log4j", module: "log4j" 
} 

Pero esto no funciona. Al agregar la exclusión a testCompile conf, automáticamente se agrega a todas las configuraciones heredadas, incluido testRuntime. Y parece que esta exclusión anula incluso la dependencia explícita que agregué.

Parece que este es el comportamiento esperado para Gradle. De the docs:

si se define una exclusión para una configuración particular, la dependencia transitiva excluidos será filtrada para todas las dependencias de la hora de resolver esta configuración o cualquier configuración heredar.

Entonces, ¿hay alguna otra manera de hacer lo que quiero lograr?

Ideas:

  • Crear un nuevo conf myTestRuntime que no se extiende a partir testCompile, y el uso que para mi ruta de clase de prueba.
    • Pero entonces tengo que duplicar todas las dependencias, tanto para testCompile y myTestRuntime.
  • Retire las exclusiones de nivel de configuración. Para todos los confs aparte de testRuntime, recorra las dependencias y elimine manualmente log4j (o agregue una exclusión de nivel dep en log4j).
    • Es esto posible? Configuration.allDependencies es de solo lectura.

Respuesta

8

Por ahora han logrado solucionar el problema, pero aún así la bienvenida a cualquier soluciones mejores.

Esto es lo que terminé haciendo:

  • Añadir una nueva configuración sólo para log4j:

    log4j(group: 'log4j', name: 'log4j', version: '1.2.15') { 
        transitive = false 
    } 
    
  • Deja la exclusión a nivel de configuración para todas las configuraciones, aparte de que uno:

    configurations.findAll {!it.name.endsWith('log4j')}.each { conf -> 
        conf.exclude group: "log4j", module: "log4j" 
    } 
    
  • Agregue la configuración de log4j a mis pruebas 'classpa th:

    test { 
        classpath += configurations.log4j 
    } 
    

De esta manera podemos obtener log4j.jar en la ruta de clase, a pesar de que se excluye de la configuración testRuntime.

+2

¿No pudo hacer su exclusión global y luego agregar el 'log4j-over-slf4j.jar'? http://www.slf4j.org/legacy.html – Snekse

+0

@Snekse que también funcionaría. buena idea –

2

No debería necesitar definir una exclusión. A menos que haya reconfigurado algo, la configuración testRuntime de un proyecto solo se usará para la tarea test de ese proyecto.

+1

Lo siento, debería haber sido más claro en mi pregunta sobre el motivo de la exclusión. Mi proyecto tiene muchas dependencias en bibliotecas de terceros, y muchas de estas bibliotecas arrastran depsitos transitivos no deseados en log4j. Podría agregar exclusiones de dep-level para cada biblioteca, pero por supuesto es mucho más fácil bloquear log4j en el nivel de configuración. (¡No quiero que vuelva a aparecer el temido log4j cada vez que agrego una nueva biblioteca!) –

4

Incluso encontré una situación similar en la que necesito excluir los frascos de chispas para que no se incluyan en frascos gruesos, pero los casos de prueba requieren el uso de frascos para chispas. La configuración inferior me funcionó. Básicamente, estoy agregando dependencias de tiempo de compilación para probar classpath. entonces para su problema a continuación la solución debería funcionar

configurations{ 
    runtime.exclude group: 'log4j' 
} 

test { 
     classpath += configurations.compile 
} 
Cuestiones relacionadas