2012-03-29 15 views
17

Utilizzando Gradle 1.0 traguardo 8.Gradle - esclude una dipendenza per una configurazione, ma non per una configurazione ereditare

mio progetto utilizza slf4j + Logback per la registrazione, quindi voglio evitare dipendenze transitive su log4j di inquinare la mia classpath. Così, ho aggiunto un'esclusione globale, in questo modo:

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

Tuttavia, sto usando una libreria di test (hadoop-minicluster), che ha una dipendenza runtime sul log4j, così ora ho bisogno per consentire una dipendenza log4j per il mio tempo di esecuzione di test . Ho provato ad aggiungere una dipendenza diretta su log4j:

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

e modificare il mio codice di esclusione (un po 'di un hack):

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

Ma questo non funziona. Aggiungendo l'esclusione al test, comp conf lo aggiunge automaticamente a tutte le configurazioni ereditanti, incluso testRuntime. E sembra che questa esclusione sovrascriva anche l'esplicita dipendenza che ho aggiunto.

Sembra che questo sia il comportamento previsto per Gradle. Da the docs:

Se si definisce un escludono per una particolare configurazione, la dipendenza transitiva esclusi verrà filtrata per tutte le dipendenze quando si risolve questa configurazione o qualsiasi configurazione ereditare.

Quindi non v'è altro modo di fare ciò che voglio raggiungere?

Idee:

  • Crea una nuova conf myTestRuntime che non si estende da testCompile, e l'uso che per il mio percorso di classe di prova.
    • Ma poi devo duplicare tutte le dipendenze sia per testCompile che per myTestRuntime.
  • Rimuovere le esclusioni a livello di configurazione. Per tutte le conf, oltre a testRuntime, eseguire il loop delle dipendenze e rimuovere manualmente log4j (o aggiungere un'esclusione a livello di dep su log4j).
    • È possibile? Configuration.allDependencies è di sola lettura.

risposta

8

Per ora sono riuscito a risolvere il problema, ma ho ancora il benvenuto eventuali soluzioni migliori.

Ecco quello che ho finito per fare:

  • aggiungere una nuova configurazione solo per log4j:

    log4j(group: 'log4j', name: 'log4j', version: '1.2.15') { 
        transitive = false 
    } 
    
  • Lascia l'esclusione a livello di configurazione per tutte le configurazioni tranne che uno:

    configurations.findAll {!it.name.endsWith('log4j')}.each { conf -> 
        conf.exclude group: "log4j", module: "log4j" 
    } 
    
  • Aggiungere la configurazione log4j al mio test classpa th:

    test { 
        classpath += configurations.log4j 
    } 
    

In questo modo possiamo ottenere log4j.jar sul percorso di classe, anche se è escluso dalla configurazione testRuntime.

+2

Non potresti fare la tua esclusione globale e quindi aggiungere il 'log4j-over-slf4j.jar'? http://www.slf4j.org/legacy.html – Snekse

+0

@Snekse che funzionerebbe anche. buona idea –

2

Non è necessario definire un'esclusione. A meno che non sia stato riconfigurato qualcosa, la configurazione testRuntime del progetto verrà utilizzata solo per l'attività test del progetto.

+1

Scusa, avrei dovuto essere più chiaro nella mia domanda sul motivo dell'esclusione. Il mio progetto ha un sacco di dipendenze su librerie di terze parti, e molte di queste librerie trascinano deps transitivi indesiderati su log4j. Potrei aggiungere esclusioni a livello di dep per ogni libreria, ma ovviamente è molto più facile bloccare log4j a livello di configurazione. (Non voglio che il temuto log4j appaia di nuovo ogni volta che aggiungo una nuova libreria!) –

4

Anche io ho riscontrato situazioni simili in cui ho bisogno di escludere barattoli di scintille dall'inclusione in barattoli di grasso, ma i casi di test richiedono l'uso di barattoli di scintille. Quindi fondamentalmente sto aggiungendo dipendenze temporali compilate per testare classpath. quindi per il tuo problema di seguito la soluzione dovrebbe funzionare

configurations{ 
    runtime.exclude group: 'log4j' 
} 

test { 
     classpath += configurations.compile 
} 
Problemi correlati