在 gradle 依赖项中,为什么 API 配置会丢弃所有传递依赖项?

In gradle dependencies, why API configurations discards all transitive dependencies?

我有一个 gradle 项目,其中包含 2 个子项目:common 和 demo。

公共项目依赖于已发布的库:

dependencies {

    implementation("eu.timepit:singleton-ops_${vs.scalaBinaryV}:0.5.0")
...

演示项目依赖于 common 作为它的一部分 API:

dependencies {

    api(project(":common")) {
        isTransitive =true
    }
}

当我编译两者时,我观察到共同的正确依赖关系:

compileClasspath - Compile classpath for source set 'main'.
+--- org.scala-lang:scala-compiler:2.12.11
|    +--- org.scala-lang:scala-library:2.12.11
|    +--- org.scala-lang:scala-reflect:2.12.11
|    |    \--- org.scala-lang:scala-library:2.12.11
|    \--- org.scala-lang.modules:scala-xml_2.12:1.0.6
+--- org.scala-lang:scala-library:2.12.11
+--- org.scala-lang:scala-reflect:2.12.11 (*)
\--- eu.timepit:singleton-ops_2.12:0.5.0
     +--- org.scala-lang:scala-compiler:2.12.8 -> 2.12.11 (*)
     +--- org.scala-lang:scala-library:2.12.8 -> 2.12.11
     \--- com.chuusai:shapeless_2.12:2.3.3
          +--- org.scala-lang:scala-library:2.12.4 -> 2.12.11
          \--- org.typelevel:macro-compat_2.12:1.1.1
               \--- org.scala-lang:scala-library:2.12.0 -> 2.12.11

但是在demo中,common下的传递依赖是空的!

compileClasspath - Compile classpath for source set 'main'.
+--- project :common
+--- org.scala-lang:scala-compiler:2.12.11
...

这会导致非常常见的类路径丢失错误,例如:

[Error] /xxx/DoubleVectorDemo.scala:9: Symbol 'type shapeless.ProductArgs' is missing from the classpath.
This symbol is required by 'object edu.umontreal.kotlingrad.shapesafe.tensor.DoubleVector'.
Make sure that type ProductArgs is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
A full rebuild may help if 'DoubleVector.class' was compiled against an incompatible version of shapeless.

那么,为 API 的一部分删除库有什么意义呢?以及如何在所有项目中覆盖此行为?

来自 gradle java-plugin 文档,

The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component. Dependencies appearing in the api configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers. Dependencies found in the implementation configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath

假设您想将 eu.timepit:singleton-ops_${vs.scalaBinaryV}:0.5.0 公开给所有公共库,那么您需要将其添加为公共模块 build.gradle.kts.

中的 api 依赖项
dependencies {

api("eu.timepit:singleton-ops_${vs.scalaBinaryV}:0.5.0")