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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21764128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:32:30  来源:igfitidea点击:

How do I exclude all instances of a transitive dependency when using Gradle?

javagradle

提问by Jens D

My gradle project uses the applicationplugin to build a jar file. As part of the runtime transitive dependencies, I end up pulling in org.slf4j:slf4j-log4j12. (It's referenced as a sub-transitive dependency in at least 5 or 6 other transitive dependencies - this project is using spring and hadoop, so everything but the kitchen sink is getting pulled in... no wait... that's there too :) ).

我的 gradle 项目使用application插件来构建一个 jar 文件。作为运行时传递依赖项的一部分,我最终将org.slf4j:slf4j-log4j12. (它在至少 5 或 6 个其他传递依赖项中被称为子传递依赖项 - 该项目使用的是 spring 和 hadoop,所以除了厨房水槽之外的所有东西都被拉进来了……不用等……那也是:) )。

I want to globally exclude the slf4j-log4j12jar from my built jar. So I've tried this:

我想slf4j-log4j12从我构建的 jar 中全局排除jar。所以我试过这个:

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

However, this seems to exclude allorg.slf4jartifacts including slf4j-api. When running under debug mode I see lines such as:

但是,这似乎排除了所有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).

I do not want to have to look up the source of each slf4j-log4j12transitive dependency and then have individual compile foo { exclude slf4j... }statements in my dependenciesblock.

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

Update:

更新:

I did also try this:

我也试过这个:

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

Which ends up excluding everythingfrom the build! As though I specified group: "*".

最终排除了构建中的所有内容!好像我指定了group: "*".

Update 2:

更新 2:

I'm using Gradle version 1.10 for this.

为此,我正在使用 Gradle 1.10 版。

采纳答案by Jens D

Ah, the following works and does what I want:

啊,以下工作并做我想要的:

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

It seems that an Exclude Ruleonly has two attributes - groupand module. However, the above syntax doesn't prevent you from specifying any arbitrary property as a predicate. When trying to exclude from an individual dependency you cannot specify arbitrary properties. For example, this fails:

似乎排除规则只有两个属性 -groupmodule。但是,上述语法并不阻止您将任意属性指定为谓词。尝试从单个依赖项中排除时,您不能指定任意属性。例如,这失败了:

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

with

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

So even though you can specify a dependency with a group:and name:you can't specify an exclusion with a name:!?!

因此,即使你可以指定一个依赖group:,并name:不能与指定排除name:!?!

Perhaps a separate question, but what exactlyis a modulethen? I can understand the Maven notion of groupId:artifactId:version, which I understand translates to group:name:version in Gradle. But then, how do I know what module (in gradle-speak) a particular Maven artifact belongs to?

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

回答by Peter Niederwieser

Your approach is correct. (Depending on the circumstances, you might want to use configurations.all { exclude ... }.) If these excludes really exclude more than a single dependency (I haven't ever noticed that when using them), please file a bug at http://forums.gradle.org, ideally with a reproducible example.

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

回答by BERGUIGA Mohamed Amine

in the example below I exclude

在下面的例子中,我排除了

spring-boot-starter-tomcat

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' 
}

回答by venom.unleashed

For excluding one or more library globally add the following to your build.gradle

要全局排除一个或多个库,请将以下内容添加到 build.gradle

configurations.all {
   exclude group:"org.apache.geronimo.specs", module: "geronimo-servlet_2.5_spec"
   exclude group:"ch.qos.logback", module:"logback-core"
}

Now the exclude block has two properties groupand module. For those of you coming from maven background, groupis same as groupIdand moduleis same as artifactId. Example: To exclude com.mchange:c3p0:0.9.2.1 following should be exclude block

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

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

回答by mark ortiz

I was using spring boot 1.5.10 and tries to exclude logback, the given solution above did not work well, I use configurations instead

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

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

回答by Arnold Schrijver

In addition to what @berguiga-mohamed-amine stated, I just found that a wildcard requires leaving the module argument the empty string:

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

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