为啥 Gradle 会降级 Grails 3.1 应用程序中的传递依赖项?

Posted

技术标签:

【中文标题】为啥 Gradle 会降级 Grails 3.1 应用程序中的传递依赖项?【英文标题】:Why does Gradle downgrade my transitive dependencies in a Grails 3.1 application?为什么 Gradle 会降级 Grails 3.1 应用程序中的传递依赖项? 【发布时间】:2016-09-06 07:32:56 【问题描述】:

我的grails-flyway 插件的传递依赖存在问题。 org.grails.plugins:grails-flyway:0.2.1 声明对 org.flywaydb:flyway-core:4.0.1 的依赖。当我将插件包含到我的 Grails 3.1.6 项目中时,Gradle 会将 Flyway 降级到版本 3.2.1。

+--- org.grails.plugins:grails-flyway:0.2.1
|    \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1

我的 Gradle 构建文件如下所示

buildscript 
    ext 
        grailsVersion = project.grailsVersion
    
    repositories 
        maven  url "https://repo.grails.org/grails/core" 
    
    dependencies 
        classpath "org.grails:grails-gradle-plugin:$grailsVersion"
        classpath "com.bertramlabs.plugins:asset-pipeline-gradle:$assetPipelinePluginVersion"
        classpath "org.grails.plugins:hibernate5:5.0.5"
        classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0'
    


version "0.40.15"
group "zsc.supporter"

apply plugin: "war"
apply plugin: "org.grails.grails-web"
apply plugin: "org.grails.grails-gsp"
apply plugin: "org.grails.grails-doc"
apply plugin: "asset-pipeline"
apply plugin: 'com.github.ben-manes.versions'

ext 
    grailsVersion = project.grailsVersion
    gradleWrapperVersion = project.gradleWrapperVersion


repositories 
    maven  url "https://repo.grails.org/grails/core" 
    maven  url "https://dl.bintray.com/saw303/plugins" 


dependencyManagement 
    imports 
        mavenBom "org.grails:grails-bom:$grailsVersion"
    
    applyMavenExclusions false


dependencies 
    compile "org.springframework.boot:spring-boot-starter-logging"
    compile "org.springframework.boot:spring-boot-autoconfigure"
    compile "org.grails:grails-core"
    compile "org.springframework.boot:spring-boot-starter-actuator"
    compile "org.springframework.boot:spring-boot-starter-tomcat"
    compile "org.grails:grails-dependencies"
    compile "org.grails:grails-web-boot"
    compile "org.grails.plugins:cache"
    compile "org.grails.plugins:scaffolding"
    compile "org.grails.plugins:hibernate4"
    compile "org.hibernate:hibernate-ehcache"
    console "org.grails:grails-console"
    profile "org.grails.profiles:web:3.1.6"
    runtime "com.bertramlabs.plugins:asset-pipeline-grails:$assetPipelinePluginVersion"
    runtime "com.h2database:h2"
    testCompile "org.grails:grails-plugin-testing"
    testCompile "org.grails.plugins:geb"
    testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.52.0"
    testRuntime "net.sourceforge.htmlunit:htmlunit:2.21"

    compile "org.grails.plugins:spring-security-core:3.0.4"
    compile "org.grails.plugins:quartz:2.0.8"
    compile "org.grails.plugins:mail:2.0.0.RC4"
    compile "eu.bitwalker:UserAgentUtils:1.18"
    compile 'org.mnode.ical4j:ical4j:1.0.7'
    compile 'org.grails.plugins:browser-detection:3.1.0'
    compile "com.googlecode.libphonenumber:libphonenumber:7.3.1"
    runtime 'org.grails.plugins:grails-flyway:0.2.1'

    testCompile "org.grails.plugins:grails-wizer:0.3"
    testCompile 'org.grails:grails-datastore-test-support:5.0.5.RELEASE'

    runtime 'mysql:mysql-connector-java:5.1.29'


task wrapper(type: Wrapper) 
    gradleVersion = gradleWrapperVersion


assets 
    minifyJs = true
    minifyCss = true

目前我不明白为什么 Gradle 会降级我的传递依赖。有人可以提供这个吗?

我知道我可以在 build.gradle 中强制使用 flyway-core:4.0.1 依赖项,但我想了解降级的原因。

UPDATE-1

当我运行 gradle dependencies | grep flyway 时,我得到以下输出。

+--- org.grails.plugins:grails-flyway:0.2.1
|    \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1
+--- org.grails.plugins:grails-flyway:0.2.1
|    \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1
+--- org.grails.plugins:grails-flyway:0.2.1
|    \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1
+--- org.grails.plugins:grails-flyway:0.2.1
|    \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1

请在pastebin 找到完整的输出。 grails-flyway 插件及其 pom.xml 可以在 Bintray 找到。

UPDATE-2

我试图根据Gradles Reference强制Gradle使用org.flywaydb:flyway-core:4.0.1

configurations.all 
    resolutionStrategy.force 'org.flywaydb:flyway-core:4.0.1'

这不会影响问题。依赖树仍然使用 flyway-core 的 3.2.1 版本。

+--- org.grails.plugins:grails-flyway:0.2.1
|    \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1

UPDATE-3

Gradles dependencyInsight 命令

gradle dependencyInsight --dependency flyway-core --configuration runtime

结果

:dependencyInsight
org.flywaydb:flyway-core:3.2.1 (selected by rule)

org.flywaydb:flyway-core:4.0.1 -> 3.2.1
\--- org.grails.plugins:grails-flyway:0.2.1
     \--- runtime 

(selected by rule)是什么意思?

“解决方案” - 或解决方法

我找不到导致 Gradle 使用 flyway-core:3.2.1 而不是 flyway-core:4.0.1 的规则。但我找到了解决问题的方法。

我将以下内容添加到我的build.gradle 以修改我的 Gradle runtime 解析策略。

configurations.runtime.resolutionStrategy 

    eachDependency  DependencyResolveDetails det ->

        if (det.requested.name == 'flyway-core' && det.requested.group == 'org.flywaydb') 
            det.useVersion(det.requested.version)
        
    

【问题讨论】:

是否还有其他依赖,依赖于org.flywaydb:flyway-core:3.2.1?正如假设,有一些依赖于旧版本的库,Gradle 只是通过降级插件的版本来解决这个问题,因为这似乎是最明显的方式 我找不到任何其他具有依赖关系树的 flyway-core 版本。 :( 您可以尝试通过运行./gradlew dependencyInsight --dependency flyway-core 来反向搜索。然后你应该能够看到谁需要 flyway-core。也许这会给你一个提示 你可以使用这个解决方案:github.com/spring-gradle-plugins/dependency-management-plugin/… 【参考方案1】:

导致它的原因是spring-boot-dependencies-1.3.3.RELEASE.pom

这迫使 flyway 版本为 3.2.1

根据Spring Boot docs,您应该能够在build.gradle 中添加这样的一行: ext['flyway.version'] = '4.0.1'

【讨论】:

你如何找出低版本有这种传递依赖的依赖?我有类似的问题,但找不到它来自哪里,所以我无法确定我应该覆盖什么ext[...] 问题是,你怎么找到它是spring-boot-dependencies-1.3.3.RELEASE.pom【参考方案2】:

转到您的 Gradle 缓存文件文件夹:

cd ~/.gradle/caches/modules-2/files-2.1

搜索这个版本号:

grep -r "3.2.1" *

你会发现哪个 pom 文件正在使用这个版本, 通常是spring-boot-dependencies-x.y.z.RELEASE.pom 中的东西:

<flyway.version>3.2.1</flyway.version>
......
<groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>$flyway.version</version>
</dependency>

也就是说,如果你使用spring-boot,它会覆盖一些依赖版本。

您可以通过在 gradle.properties 文件中添加以下行来再次覆盖它:

flyway.version=4.0.1

我遇到了类似的问题并在上面浪费了几个小时。 所以我把这些信息留在这里,希望如果你遇到这个问题,这可以节省你的时间

【讨论】:

以上是关于为啥 Gradle 会降级 Grails 3.1 应用程序中的传递依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

AS 3.1 多library合并打包成aar的正确方式(fat-aar)

Gradle 3.5 搭建 Grails 3.0 项目配置

用于 Grails 2.0 的 Grails/Gradle 插件

Grails & gradle:插件管理

Gradle / Grails 应用程序

Meteor 版本求解器:为啥“流星更新”会降级软件包?