Gradle - 排除配置的依赖关系,但不包括继承配置

时间:2012-03-29 03:05:02

标签: gradle dependencies

使用Gradle 1.0里程碑8。

我的项目使用slf4j + Logback进行日志记录,因此我想阻止log4j上的任何传递deps污染我的类路径。因此,我添加了一个全局排除,如下所示:

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

但是,我正在使用一个测试库(hadoop-minicluster),它对log4j有运行时依赖性,所以我现在需要为我的测试运行时允许一个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

  

如果为特定配置定义排除,则在解析此配置或任何继承配置时,将针对所有依赖项筛选排除的传递依赖关系。

那么还有其他方法可以实现我想要实现的目标吗?

思路:

  • 创建一个不从testCompile扩展的新conf myTestRuntime,并将其用于我的测试类路径。
    • 但是我必须复制testCompile和myTestRuntime的所有依赖项。
  • 删除配置级排除项。对于除testRuntime之外的所有confs,循环依赖并手动删除log4j(或在log4j上添加dep-level排除)。
    • 这甚至可能吗? Configuration.allDependencies是只读的。

3 个答案:

答案 0 :(得分: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配置添加到我的测试的类路径中:

    test {
        classpath += configurations.log4j
    }
    

这样我们就可以将log4j.jar放到类路径上,即使它已从testRuntime配置中排除。

答案 1 :(得分:5)

即使我遇到了类似的情况,我需要在胖罐中排除火花罐,但测试用例需要火花罐才能执行。所以下面的配置对我有用。所以基本上我正在添加编译时依赖项来测试类路径。所以对于你的问题,解决方案应该工作

configurations{
    runtime.exclude group: 'log4j'
}

test {
        classpath += configurations.compile
}

答案 2 :(得分:2)

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