首页 > 解决方案 > 无法理解 Gradle 的默认依赖解析策略

问题描述

我已经构建并上传了一个 Java 库到一个私有的 Artifactory 空间。假设该库的 Gradle 标识符为com.mycompany:MyLibrary:1.0.0,已上传到https://artifactory.mycompany.com/artifactory/libs-release并且在 JCenter 中不存在。该库依赖于另一个上传到https://artifactory.mycompany.com/artifactory/libs-release但可从 JCenter 公开获得的库。假设第二个库的 Gradle 标识符为com.google.code.findbugs:jsr305:3.0.0.

作为 Java 应用程序中 Java 库的使用者,我的依赖项列表如下:

dependencies {
    implementation 'com.mycompany:MyLibrary:1.0.0'
}

值得注意的是,我不需要显式声明com.google.code.findbugs:jsr305:3.0.0依赖项,因为它将被传递解决。

此外,出于安全原因,我想在 JCenter 上方订购我的私有 Artifactory 存储库,如下所示:

repositories {
    maven {
        url 'https://artifactory.mycompany.com/artifactory/libs-release'
    }
    jcenter()
}

但是,当我尝试构建我的 Java 应用程序时,我遇到了以下错误:

Execution failed for task ':bootJar'.
> Could not resolve all files for configuration ':runtimeClasspath'.
   > Could not find jsr305-3.0.0.jar (com.google.code.findbugs:jsr305:3.0.0).
     Searched in the following locations:
         https://artifactory.mycompany.com/artifactory/libs-release/com/google/code/findbugs/jsr305/3.0.0/jsr305-3.0.0.jar

从这个错误中可以看出,jsr305-3.0.0仅在我的私有 Artifactory 存储库中搜索了该工件,而不是在 JCenter 中。jsr305-3.0.0如果在我的私有 Artifactory 存储库中找不到该工件,我本来希望 Gradle 会在 JCenter 中搜索它。

如果我重新排序存储库以便首先声明 JCenter,如下所示...

repositories {
    jcenter()
    maven {
        url 'https://artifactory.mycompany.com/artifactory/libs-release'
    }
}

...然后构建成功完成。

我正在经历 Gradle 如何解决依赖关系的预期行为,还是这是一个错误?如果这是预期的行为,我可以做些什么来更改依赖解析策略,以便我可以在 JCenter 上方声明我的私有 Artifactory 存储库?

标签: gradleartifactory

解决方案


JCenter 中的元数据优于自定义私有 Artifactory 空间中的元数据。

Gradle 检查所有存储库以找到最佳元数据并使用它。

查看Gradle 文档中声明存储库页面中的以下引用。

首先,从声明多个存储库部分:

声明的顺序决定了 Gradle 如何在运行时检查依赖项。如果 Gradle 在特定存储库中找到模块描述符,它将尝试从同一存储库下载该模块的所有工件。您可以了解有关依赖项下载的内部工作原理的更多信息。

其次,从支持的存储库类型部分:

由于 Gradle 更喜欢使用描述符是从真实元数据创建而不是生成的模块,因此平面目录存储库不能用于使用构建中声明的其他存储库中的真实元数据覆盖工件。

例如,如果 Gradle 在平面目录存储库中仅找到 jmxri-1.2.1.jar,但在另一个支持元数据的存储库中找到 jmxri-1.2.1.pom,它将使用第二个存储库来提供模块。


推荐阅读