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

Posted

技术标签:

【中文标题】使用 Gradle 时如何排除传递依赖项的所有实例?【英文标题】:How do I exclude all instances of a transitive dependency when using Gradle? 【发布时间】:2014-03-12 21:57:41 【问题描述】:

我的 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 版。

【问题讨论】:

您可能希望接受您的问题的答案;这很有礼貌,更能激发你回答问题的兴趣 【参考方案1】:

啊,下面的作品和我想要的:

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

Exclude Rule 似乎只有两个属性 - groupmodule。但是,上述语法并不妨碍您将任意属性指定为谓词。当试图从单个依赖项中排除时,您不能指定任意属性。例如,这会失败:

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:!?! 指定排除项!

也许是一个单独的问题,那么究竟是什么模块?我可以理解 groupId:artifactId:version 的 Maven 概念,我理解它在 Gradle 中转换为 group:name:version。但是,我怎么知道一个特定的 Maven 工件属于哪个模块(在 gradle 中)?

【讨论】:

这似乎是对Gradle forums 的更好讨论。 完成了 - forums.gradle.org/gradle/topics/… 呃,我只是为这个确切的问题而苦苦挣扎。我发现用 gradle 做任何事情都异常困难,尤其是解决大型项目的冲突。我很乐意在 gradle 的 dsl 上使用带有 xsd 验证的详细 xml “名称:”应该是“模块:”,然后它会为你工作:) 为了将来我和其他人的利益,我想从我的 war 包中排除所有依赖库(Gradle 3.3)。因此,我没有一一列出,而是简单地做了configurations runtime.exclude group: '*' 【参考方案2】:

要全局排除一个或多个库,请将以下内容添加到您的 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"

【讨论】:

谢谢我明白,他们可以说模块意味着名称【参考方案3】:

你的方法是正确的。 (根据具体情况,您可能希望使用configurations.all exclude ... 。)如果这些排除项确实排除了多个依赖项(我在使用它们时从未注意到这一点),请在http://forums.gradle.org 提交错误,最好使用一个可重现的例子。

【讨论】:

configurations.all 正是我想要的。感谢彼得的帖子【参考方案4】:

在下面的例子中我排除了

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' 

【讨论】:

【参考方案5】:

我使用的是spring boot 1.5.10并尝试排除logback,上面给出的解决方案效果不佳,我改用配置

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

【讨论】:

【参考方案6】:

除了@berguiga-mohamed-amine 所说的,我刚刚发现通配符需要将模块参数保留为空字符串:

compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") 
    exclude group: 'org.apache.httpcomponents', module: ''
    exclude group: 'org.slf4j', module: ''

【讨论】:

【参考方案7】:

compile 已弃用,取而代之的是 implementation。因此,对于那些运行较新版本 gradle 的解决方案:

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

【讨论】:

以上是关于使用 Gradle 时如何排除传递依赖项的所有实例?的主要内容,如果未能解决你的问题,请参考以下文章

Android apk - 如何使用 gradle 从 3rd 方依赖项中排除 .so 文件

Gradle - 排除嵌套的传递依赖

Gradle 传递依赖排除未按预期工作。 (我如何摆脱 com.google.guava:guava-jdk5:13.0 ?)

Gradle 排除依赖非常混乱

Android Gradle 插件Gradle 依赖管理 ⑦ ( dependencies 传递依赖设置 | transitive 关闭依赖传递配置 | exclude 排除子依赖配置 )

Android Gradle 插件Android 依赖管理 ⑥ ( 依赖冲突处理 | transitive 依赖传递设置 | exclude 依赖排除设置 | force 强制指定依赖库 )