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

Mic*_*ers 8 java dependency-management gradle

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

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

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

// settings.gradle
include ':A', ':B'
Run Code Online (Sandbox Code Playgroud)
// 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"
    }
}
Run Code Online (Sandbox Code Playgroud)

如你所见,一个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
[...]
Run Code Online (Sandbox Code Playgroud)

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

lan*_*ava 6

看到这个问答.如果未指定配置,Gradle将选择default从中扩展的配置runtime.快速解决方法是使用

compile project(path: ":B", configuration: "compile")
Run Code Online (Sandbox Code Playgroud)

  • 我用@dmoebius离线讨论了这个问题,虽然答案是完全正确和有用的,但是应该记住以下几点:显式地指定`compile`配置确实会阻止你的项目编译类路径被传递的运行时依赖性"污染",但是你的项目*runtime*classpath现在也缺少这些传递的运行时依赖项.所以你可以使用正在使用的`default`配置,或者你必须添加第二个依赖项来映射`runtime`到`runtime`:`runtime project(path:":B",configuration:"runtime")` (3认同)
  • `compile project(':B')`方法从项目B获取`default`配置,并将它添加到项目A的`compile`配置中.因此,将B的`runtime`依赖项添加到A的`compile`依赖项是合乎逻辑的 (2认同)