Gradle 渐变-排除配置的依赖项,但不排除继承配置的依赖项

Gradle 渐变-排除配置的依赖项,但不排除继承配置的依赖项,gradle,dependencies,Gradle,Dependencies,使用Gradle 1.0里程碑8 我的项目使用slf4j+Logback进行日志记录,所以我想防止log4j上的任何可传递的dep污染我的类路径。因此,我添加了一个全局排除,如下所示: configurations { all*.exclude group: "log4j", module: "log4j" } 但是,我正在使用一个测试库(hadoop minicluster),它对log4j具有运行时依赖性,因此我现在需要允许我的测试运行时具有log4j依赖性。我尝试添加对log4j

使用Gradle 1.0里程碑8

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

configurations {
    all*.exclude group: "log4j", module: "log4j"
}
但是,我正在使用一个测试库(
hadoop minicluster
),它对log4j具有运行时依赖性,因此我现在需要允许我的测试运行时具有log4j依赖性。我尝试添加对log4j的直接依赖:

testRuntime group: "log4j", name: "log4j", version: "1.2.15"
编辑我的排除代码(有点黑客行为):

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

这似乎是Gradle的预期行为。发件人:

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

那么,有没有其他方法来实现我的目标呢

想法:

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

目前我已经设法解决了这个问题,但我仍然欢迎任何更好的解决方案

以下是我最后做的:

  • 仅为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配置中排除。

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

甚至我也遇到过类似的情况,即我需要将spark jar排除在fat jar中,但测试用例需要执行spark jar。所以下面的配置对我来说很有用。因此,基本上我是在向测试类路径添加编译时依赖项。所以对于你下面的问题,解决方案应该是可行的

configurations{
    runtime.exclude group: 'log4j'
}

test {
        classpath += configurations.compile
}

对不起,我应该在我的问题中更清楚地说明排除的原因。我的项目对第三方库有很多依赖性,其中许多库在log4j上拖入了不需要的可传递dep。我可以为每个库添加dep级别的排除,但当然在配置级别阻止log4j要容易得多。(我不想每次添加新库时都再次出现可怕的log4j!)您不能执行全局排除,然后添加
log4j-over-slf4j.jar
configurations{
    runtime.exclude group: 'log4j'
}

test {
        classpath += configurations.compile
}