如何在使用Gradle时排除所有传递依赖项的实例?

157

我的Gradle项目使用application插件来构建jar文件。作为运行时传递依赖项的一部分,我最终会拉入org.slf4j:slf4j-log4j12。(它至少在5或6个其他传递依赖项中被引用为子传递依赖项 - 这个项目正在使用Spring和Hadoop,所以除了厨房水槽以外的所有东西都被拉进来了......等等,那也在里面 :) )。

我想要从构建的jar文件中全局排除slf4j-log4j12 jar。因此,我尝试了这个:

configurations {
  runtime.exclude group: "org.slf4j", name: "slf4j-log4j12"
}

然而,这似乎排除了org.slf4j所有工件,包括slf4j-api。在调试模式下运行时,我会看到如下行:

org.slf4j#slf4j-api is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-simple is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-log4j12 is excluded from org.apache.hadoop:hadoop-common:2.2.0(runtime).

我不想要查找每个slf4j-log4j12传递依赖项的源代码,然后在我的dependencies块中使用单独的compile foo { exclude slf4j... }语句。

更新:

我也试过这个方法:

configurations {
  runtime.exclude name: "slf4j-log4j12"
}

这将导致构建中所有内容都被排除在外!就好像我指定了group:“*”

更新2:

我正在使用Gradle版本1.10进行此操作。

8个回答

191
啊,以下的代码可以正常工作并且实现了我想要的效果:

Ah, the following works and does what I want:


configurations {
  runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
}

看起来一个排除规则只有两个属性——groupmodule
因此,如果要从单个依赖项中排除某些内容,可以这样做:

dependencies {
  compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
    exclude group: "org.slf4j", module: "slf4j-log4j12"
  }
}

然而,上述语法并不阻止您将任意属性指定为谓词。但是,当您尝试从个别依赖项中排除时,您不能指定任意属性。例如,以下操作将失败:

dependencies {
  compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
    exclude group: "org.slf4j", name: "slf4j-log4j12"
  }
}

具有

No such property: name for class: org.gradle.api.internal.artifacts.DefaultExcludeRule

所以,尽管您可以使用 group:name: 指定依赖项,但却无法使用 name: 指定排除项!?!

或许这是一个单独的问题,但是什么是一个模块呢?我能理解Maven的groupId:artifactId:version概念,我知道它在Gradle中对应于group:name:version。但是,我怎么知道一个特定的Maven构件(在Gradle中的说法是"module")属于哪个模块呢?


2
这似乎更适合在Gradle论坛进行讨论。 - superEb
21
呃,我刚刚也遇到了这个问题。我发现在gradle上做任何事情都特别难,特别是在解决大型项目中的冲突。我宁愿使用冗长的XML和XSD验证,而不是使用gradle的DSL。 - cjbooms
2
“name:” 应该改为 “module:”,这样就可以正常工作了 :) - GuyK
1
为了将来的我和其他人的利益,我想从我的war包中排除所有依赖库(Gradle 3.3)。因此,我不是列出每一个依赖库,而是简单地执行了configurations { runtime.exclude group: '*' } - sfdurbano
1
没有名称对象,我必须使用 module。例如:exclude group: "org.apache.logging.log4j", module: "log4j-slf4j-impl" - prayagupa
显示剩余3条评论

75
在build.gradle中,要全局排除一个或多个库,请添加以下内容。
configurations.all {
   exclude group:"org.apache.geronimo.specs", module: "geronimo-servlet_2.5_spec"
   exclude group:"ch.qos.logback", module:"logback-core"
}

现在排除块有两个属性 groupmodule。对于那些来自 Maven 背景的人,groupgroupId 相同,moduleartifactId 相同。 例如:要排除 com.mchange:c3p0:0.9.2.1,应使用以下排除块:

exclude group:"com.mchange", module:"c3p0"

1
谢谢,我明白了,他们本可以说模块的意思是名称。 - Remario

35

你的方法是正确的。(根据情况,你可能想使用 configurations.all { exclude ... }。)如果这些排除项确实排除了不止一个依赖项(我在使用它们时从未注意到过),请在http://forums.gradle.org上报告错误,最好附带可重现的示例。


3
“configurations.all {}”正是我正在寻找的。感谢Peter的文章。 - pczeus

29

以下示例中我排除

spring-boot-starter-tomcat

compile("org.springframework.boot:spring-boot-starter-web") {
     //by both name and group
     exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' 
}

14

我曾使用Spring Boot 1.5.10并尝试排除Logback,但上面提供的解决方案效果不佳。我改为使用配置。

configurations.all {
    exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
}

9

compile已经被弃用,而且已被implementation所取代。因此,对于运行较新版本gradle的开发者,解决方案如下:

implementation("org.springframework.boot:spring-boot-starter-web") {
     exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' 
}

8
除了@berguiga-mohamed-amine所说的内容外,我发现通配符需要将模块参数保留为空字符串:
compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") {
    exclude group: 'org.apache.httpcomponents', module: ''
    exclude group: 'org.slf4j', module: ''
}

2
这是针对 Kotlin DSL (build.gradle.kts) 的,它可以防止您使用错误的属性。
从所有配置中排除该库(包括 `implementation`、`runtimeOnly` 等):
configurations.all {
    exclude(group = "ir.mahozad.android", module = "pie-chart")
    // OR exclude("ir.mahozad.android", "pie-chart")
}

// Another notation:
// configurations {
//     all {
//         exclude(group = "ir.mahozad.android", module = "pie-chart")
//     }
// }

从单个配置中排除库(例如implementation):
configurations.implementation {
    exclude(group = "ir.mahozad.android", module = "pie-chart")
}

// Another notation:
// configurations {
//     implementation {
//         exclude(group = "ir.mahozad.android", module = "pie-chart")
//     }
// }

排除单个依赖项的库:
dependencies {
    // ...
    implementation("ir.mahozad.android:charts:1.2.3") {
        exclude(group = "ir.mahozad.android", module = "pie-chart")
    }
}

1
考虑使用 configureEach 而不是 all 来避免不必要的配置。 - RomanMitasov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接