【问题标题】:Remove transitive classpath dependency in gradle删除 gradle 中的传递类路径依赖项
【发布时间】:2016-05-04 10:39:06
【问题描述】:

我们正在运行一个带有 gradle 的 spring-boot 应用程序。

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

buildscript {
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.2.RELEASE") 
    }
}

不幸的是,这个插件附带了一个依赖项 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'
}

没有任何作用。

欢迎任何提示。

【问题讨论】:

    标签: java gradle spring-boot dependency-management


    【解决方案1】:

    如果您尝试排除

    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', module: 'log4j-slf4j-impl'
        }
    }
    

    【讨论】:

    • 等一下! spring-boot-gradle-plugin 没有 log4j-slf4j-impl 作为传递依赖。它来自其他地方。
    • 嗯不,一旦我从 gradle 脚本中删除它,依赖关系也消失了。
    • 使用 gradle 依赖任务查看所有传递依赖:gist.github.com/foragerr/3dcd361f8f277d100325
    • 抱歉,gradle 插件根本没有出现在依赖关系图中。我认为它是插件的原因是,一旦我删除它,依赖关系也消失了。在依赖关系树中,我只看到带有 (*) 的版本 2.4.1,这意味着由规则强制执行。
    • 你能不能也试试:configurations.classpath.exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl' buildscript 块内外。
    【解决方案2】:

    当我想确保从未将依赖项添加到项目中时,我通常会回退到此。

    configurations {
        all*.exclude group: 'org.apache.logging.log4j', module: 'log4j-slf4j-impl', version '2.4.1'
    }
    

    但是你确定你需要排除依赖吗?它不应该是构建 jar/war 的一部分。 您可以使用“gradlew dependencies”检查所有依赖项。

    【讨论】:

    • 这行不通,因为我想使用它的 2.5 版。抱歉,我没有在问题中提到这一点。
    • 我以前没用过,但你也可以将版本添加到排除项中。我相应地更新了答案。
    • 不,这是不可能的
    【解决方案3】:

    问题是我将 log4j 声明为运行时依赖项:

      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 声明为编译依赖,2.4.1 就消失了...

    【讨论】:

      【解决方案4】:

      两步,追踪传递依赖,然后将其从负责的库中排除。

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

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

      在我的用例中,日志记录被明确声明为编译时依赖项,因此如下所示。如果log4j 在其他任何地方,您会看到有问题的库以及 v2.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'
              }
          }
      }
      

      我的意见是,我可能不想一直在resolutionStrategy 中添加检查,所以最好在dependencyInsights 中跟踪它。这也意味着在两个地方更新版本,如果另一个开发人员不知道 gradle 的 resolutionStrategy 是如何工作的,那么他们将有“奇怪”的行为......例如。我将log4j 更新为2.7,但它仍然与2.5 一起构建?!?!

      但两者都是有效的方法

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-15
        • 1970-01-01
        • 1970-01-01
        • 2017-06-15
        相关资源
        最近更新 更多