Java 删除gradle中的可传递类路径依赖项

Java 删除gradle中的可传递类路径依赖项,java,gradle,spring-boot,dependency-management,Java,Gradle,Spring Boot,Dependency Management,我们正在用gradle运行spring boot应用程序 为了包含spring引导插件,我们将其添加为依赖项: buildscript { dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.2.RELEASE") } } ext { log4jVersion="2.5" } runtime ( "or

我们正在用gradle运行spring boot应用程序

为了包含spring引导插件,我们将其添加为依赖项:

buildscript {
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.2.RELEASE") 
    }
}
  ext {
       log4jVersion="2.5"
  }
  runtime (
            "org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion",
            "org.apache.logging.log4j:log4j-api:$log4jVersion",
            "org.apache.logging.log4j:log4j-core:$log4jVersion"
        )
不幸的是,这个插件附带了对
org.apache.logging.log4j:log4j-slf4j-impl:2.4.1

我想把它排除在外

已尝试添加以下内容:

  dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.2.RELEASE") {
            exclude group: 'org.apache.logging.log4j'
        }
    }
这不管用

还添加:

configurations {
    classpath.exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
}
没有任何效果


欢迎任何提示。

如果您试图排除

org.apache.logging.log4j:log4j-slf4j-impl:2.4.1
试一试


当我想确保一个依赖项从未添加到项目中时,我通常会回过头来考虑这个问题

configurations {
    all*.exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl', version '2.4.1'
}
但是您确定需要排除依赖项吗。它不应该是构建jar/war的一部分。
您可以使用“gradlew dependencies”检查所有依赖项。

不知何故,问题在于我将log4j声明为运行时依赖项:

buildscript {
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.2.RELEASE") 
    }
}
  ext {
       log4jVersion="2.5"
  }
  runtime (
            "org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion",
            "org.apache.logging.log4j:log4j-api:$log4jVersion",
            "org.apache.logging.log4j:log4j-core:$log4jVersion"
        )
这导致了2.4.1版被一些编辑器作为编译依赖项获取的情况

因此,我在类路径上有2.4.1和2.5


一旦我将log4j声明为compile dependency 2.4.1就消失了…

gradle dependencies
为您提供了完整的列表,包括可传递项。如果您的项目很小,这可能会有帮助,但对于大型企业构建。。。信息太多了。您可以随意搜索,但我们可以从
dependencyInsight
中获得更多关键信息

gradle dependencyInsight——dependency someDependency
查找依赖项可能进入构建的所有位置。如果您有多个版本,这将有助于明确版本的来源

在我的用例中,日志被显式声明为编译时依赖项,如下所示。如果
log4j
在其他地方,您将看到有问题的库以及v
2.5
的编译时声明

我必须在每个子模块上明确地运行它

$ gradle util:dependencyInsight --dependency org.apache.logging.log4j
Configuration on demand is an incubating feature.
:util:dependencyInsight
org.apache.logging.log4j:log4j-api:2.5
+--- compile
\--- org.apache.logging.log4j:log4j-core:2.5
     \--- compile

org.apache.logging.log4j:log4j-core:2.5
\--- compile

(*) - dependencies omitted (listed previously)

BUILD SUCCESSFUL

Total time: 0.933 secs
现在,一旦您知道从何处排除依赖项,只需像以前一样删除它。您可以再次运行
dependencyInsights
进行确认

dependencies {
    // found through `gradle dependencyInsight --dependency org.apache.logging.log4j`
    classpath("someOtherGroup:someOtherArtifactId:1.0") {
        exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl'
    }
}
另一种解决方案可能是覆盖依赖项解析器,并强制版本为
2.5

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (details.requested.group == "org.apache.logging.log4j") {
            println "Updating version for: $details.requested.group:$details.requested.name:$details.requested.version --> 2.5"
            details.useVersion '2.5'
        }
    }
}
我的意见是,我可能不想一直在
解决方案策略
中添加检查,因此最好在
dependencyInsights
中跟踪检查。这也意味着在两个地方更新版本,如果另一个开发人员不知道gradle的
解决方案策略如何工作,那么他们将有“奇怪”的行为。。。例如,我将
log4j
更新为
2.7
,但它仍然使用
2.5
构建


但这两种方法都是有效的

等一下!不将log4j-slf4j-impl作为可传递依赖项。它来自其他地方。不,一旦我从gradle脚本中删除它,依赖关系也就消失了。请使用gradle依赖关系查看所有可传递的依赖关系任务:抱歉,gradle插件根本不出现在依赖关系图中。我之所以认为它是插件,是因为一旦我删除它,依赖性也就消失了。在依赖项树中,我只看到版本2.4.1中带有(*),这意味着由规则强制执行。请您也尝试一下:
configurations.classpath.exclude group:'org.apache.logging.log4j',模块:'log4j-slf4j-impl'
,无论是在buildscript块中还是在buildscript块外。这都不起作用,因为我想使用版本2.5。抱歉,我在问题中没有提到。我以前没有使用过它,但您也可以将该版本添加到排除中。我相应地更新了答案。不,这是不可能的