2012-03-29 61 views
17

使用摇篮1.0里程碑8摇篮 - 排除配置的依赖,但没有为继承配置

我的项目使用SLF4J +的logback日志记录,所以我想,以防止任何log4j的传递DEPS从我的污染类路径。因此,我添加了一个全球性的排斥,就像这样:

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

不过,我使用的这对log4j的运行时相关性的测试库(hadoop-minicluster),所以现在我需要让我的测试运行时log4j的依赖。我试了log4j的增加的直接依赖:

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

和编辑我排除代码(一个黑客位的):

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

但是,这是行不通的。将排除添加到testCompile conf中会自动将其添加到所有继承配置中,包括testRuntime。而且这种排除似乎也会覆盖我所添加的显式依赖。

看来,这是Gradle的预期行为。从the docs

如果你定义一个排除特定配置,排除传递依赖将解决这一配置或任何继承配置时被过滤了所有的依赖。

那么还有什么其他方式可以做我想做的事吗?

思路:

  • 创建一个新的conf myTestRuntime不从testCompile延伸,并使用了我的测试类路径。
    • 但是,我必须复制testCompile和myTestRuntime的所有依赖关系。
  • 删除配置级别排除。对于除testRuntime以外的所有confs,循环依赖并手动删除log4j(或在log4j上添加dep级别的排除)。
    • 这是可能的吗? Configuration.allDependencies是只读的。

回答

8

现在我已成功地解决这个问题,但我仍然欢迎任何更好的解决方案。

这里是我落得这样做:

  • 添加一个新的配置只是log4j的:

    log4j(group: 'log4j', name: 'log4j', version: '1.2.15') { 
        transitive = false 
    } 
    
  • 从一个离开配置级别排除所有的配置相距:

    configurations.findAll {!it.name.endsWith('log4j')}.each { conf -> 
        conf.exclude group: "log4j", module: "log4j" 
    } 
    
  • 将log4j配置添加到我的测试'classpa日:

    test { 
        classpath += configurations.log4j 
    } 
    

这样我们就可以得到log4j.jar到类路径,尽管它是从testRuntime配置排除。

+2

难道你不做你的全局排除,然后添加'log4j-over-slf4j.jar'? http://www.slf4j.org/legacy.html – Snekse 2015-03-26 22:53:59

+0

@Snekse也可以。好主意 – 2016-03-16 22:21:58

2

您不应该定义排除。除非您重新配置了某项内容,否则项目的testRuntime配置将仅用于该项目的test任务。

+1

对不起,我应该在关于排除原因的问题上更加清楚。我的项目对第三方库有很多依赖关系,并且其中许多库在log4j中拖拽了不需要的传递层。我可以为每个库添加dep级别的排除,但当然在配置级别阻止log4j要容易得多。 (我不希望每次添加新库时都会再次出现可怕的log4j!) – 2012-03-30 00:38:50

4

即使我遇到类似的情况,我需要从包括在脂肪罐中排除火花瓶,但测试用例需要火花瓶执行。以下配置为我工作。所以基本上我加入了编译时间依赖来测试classpath。所以对于你的问题解决方案应该工作

configurations{ 
    runtime.exclude group: 'log4j' 
} 

test { 
     classpath += configurations.compile 
}