gradle 包括传递运行时依赖作为编译依赖

gradle includes transitive runtime dependency as compile dependency

我在 gradle 依赖管理中遇到了一个奇怪的行为,其中项目 A 引用项目 B 作为编译依赖,项目 B 引用库 C 作为运行时依赖。现在我可以在我的项目 A 中使用库 C 中的 类。

我的问题:(为什么)这是错误还是功能?

可以使用 gradle 2.9 和 2.10 以及以下最小设置重现该问题:

// settings.gradle
include ':A', ':B'
// build.gradle
allprojects {
    apply plugin: 'java'
    apply plugin: 'maven'

    repositories {
        mavenLocal()
        mavenCentral()
    }
}

project(':A') {
    dependencies {
        compile project(':B')
    }
}

project(':B') {
    dependencies {
        runtime "org.slf4j:slf4j-log4j12:1.7.13"
    }
}

如您所见,gradle :A:dependencies 显示

[...]

compile - Compile classpath for source set 'main'.
\--- project :B
     \--- org.slf4j:slf4j-log4j12:1.7.13
          +--- org.slf4j:slf4j-api:1.7.13
          \--- log4j:log4j:1.2.17
[...]

并且在项目 A 中的 java 代码中完全可以使用 log4j。

参见this问答。如果您不指定配置,Gradle 将选择从 runtime 扩展的 default 配置。快速解决方法是使用

compile project(path: ":B", configuration: "compile")

在 Android 库 (aar) 传递运行时依赖项的情况下,从 5.0 开始 Gradle 修复了此问题。