4

我发现我的库的传递依赖项没有显示在应用程序中,尤其是当我的库中使用 maven BoM 时。

当没有 BoM 时,传递依赖出现在应用程序中。这是 3rd-party-lib 在 my-app 中正确显示为运行时依赖项的示例。

[my-app] --> [my-lib] --> [3rd-party-lib]

但是当我在我的库中使用 BoM(如下图所示)时,它不会在 my-app 中显示为运行时依赖项。这会导致运行时崩溃!

[my-app] --> [my-lib] --> [bom] --> [3rd-party-lib]

这是可重现此问题的代码:

// bom/build.gradle

plugins {
    id 'java-platform'
    id 'maven-publish'
}

publishing {
    publications {
        bom(MavenPublication) {
            from components.javaPlatform
        }
    }
}

group "com.example"
version "0.0.3"

dependencies {
    constraints {
        api "com.jakewharton.timber:timber:4.7.1" // 3rd-party-lib
    }
}
// mylibrary/build.gradle

apply plugin: 'com.android.library'
<<removed stuff for brevity>>

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'

    api platform("com.example:bom:0.0.3")
    api "com.jakewharton.timber:timber"
}

// This helps to publish this library to maven local.
apply from: "https://raw.githubusercontent.com/sky-uk/gradle-maven-plugin/1.0.4/gradle-mavenizer.gradle"
// myapp/build.gradle

apply plugin: 'com.android.application'
<<removed stuff for brevity>>

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'

    implementation "com.example:mylibrary:1.0.0"
}

在这种情况下,木材是 3rd-party-lib。如前所述,当 mylibrary 使用 BoM 时,这不会显示在应用程序中。因此,每当应用调用内部需要木材的库代码时,应用就会崩溃。

如何确保 mylibrary 将传递依赖项引入应用程序?

PS:我发布到 mylibrary 到本地的 maven。

4

2 回答 2

1

我未经证实(!)的猜测是,您应用到您的库的这个“Gradle Maven 插件”</a> 可能是罪魁祸首。它对已发布的 POM 中记录的依赖项进行一些修改,这对于 BOM 来说可能是虚假的。

FWIW,整个设置对我来说没有这个插件(以及一个普通的 Java 库/应用程序,因为我当前的计算机上没有 Android SDK)。您可以在下面找到(完整的)工作设置。

我知道,这可能不是一个准确的答案。也许它仍然可以帮助您追踪问题。

最小的工作设置

.
├── bom
│   └── build.gradle
├── myapp
│   └── build.gradle
└── mylibrary
    └── build.gradle

bom/build.gradle

与问题中的内容完全相同

mylibrary/build.gradle

apply plugin: 'java-library'

group "com.example"
version "1.0.0"

repositories {
    jcenter()
}

dependencies {
    api platform("com.example:bom:0.0.3")
    api "com.jakewharton.timber:timber"
}

myapp/build.gradle

plugins {
    id 'java'
}

repositories {
    jcenter()
}

dependencies {
    implementation "com.example:mylibrary:1.0.0"
}

检查它是否有效

myapp/目录运行它(使用上面未包含的 Gradle 6.1.1 Wrapper):

./gradlew dependencies --include-build ../mylibrary/ --include-build ../bom/
于 2020-02-02T20:08:23.723 回答
1

正如 Maven传递依赖项所读取的那样,这按预期工作(这也适用于 Gradle):

Maven 通过自动包含传递依赖项来避免发现和指定您自己的依赖项所需的库。

如果您真的想强制它,理论上 exclude您可以从 Gradle 依赖项中添加它们,而是将它们添加为单独的(非传递)依赖项 - 但这不是必需的。这才有意义,例如。打算提供更新版本时 - 或处理版本冲突时。如果目标是拥有独立的离线项目,还有其他方法

于 2020-01-28T08:10:56.640 回答