为什么Gradle在编译/运行时类路径中不包含传递依赖?

Fra*_*oth 12 build build-system dependency-management

我正在学习Gradle如何工作,我无法理解它如何解决项目传递依赖.

目前,我有两个项目:

  • projectA:它对外部库有一些依赖性
  • projectB:对projectA只有一个依赖项

无论我如何尝试,当我构建projectB时,gradle不包含projectB的编译或运行时类路径中的任何projectA依赖项(X和Y).我只是通过在projectB的构建脚本中包含projectA的依赖项来设法使它工作,在我看来这没有任何意义.这些依赖项应自动附加到projectB.我很确定我错过了什么,但我无法弄清楚是什么.

我已经读过"lib dependencies",但它似乎只适用于此处描述的本地项目,而不适用于外部依赖项.

这是我在根项目中使用的build.gradle(包含projectA和projectB的那个):

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.3'
    }
}

subprojects {
    apply plugin: 'java'
    apply plugin: 'idea'

    group = 'com.company'

    repositories {
        mavenCentral()
        add(new org.apache.ivy.plugins.resolver.SshResolver()) {
            name = 'customRepo'
            addIvyPattern "ssh://.../repository/[organization]/[module]/[revision]/[module].xml"
            addArtifactPattern "ssh://.../[organization]/[module]/[revision]/[module](-[classifier]).[ext]"
        }
    }

    sourceSets {
        main {
            java {
                srcDir 'src/'
            }
        }
    }

    idea.module { downloadSources = true }

    // task that create sources jar
    task sourceJar(type: Jar) {
        from sourceSets.main.java
        classifier 'sources'
    }

    // Publishing configuration
    uploadArchives {
        repositories {
            add project.repositories.customRepo
        }
    }

    artifacts {
        archives(sourceJar) {
            name "$name-sources"
            type 'source'
            builtBy sourceJar
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这个只关注projectA:

version = '1.0'
dependencies {
    compile 'com.company:X:1.0'
    compile 'com.company:B:1.0'
}
Run Code Online (Sandbox Code Playgroud)

这是projectB使用的那个:

version = '1.0'
dependencies {
    compile ('com.company:projectA:1.0') {
        transitive = true
    }
}
Run Code Online (Sandbox Code Playgroud)

提前感谢您的帮助,请为我的英语不好道歉.

And*_*ton 5

我知道这个特定版本的问题已经解决了,但是我的搜索把我带到了这里,我希望我可以省去一些人弄清楚这个问题的麻烦。

坏的 foo/build.gradle

dependencies {
    implementation 'com.example:widget:1.0.0'
}
Run Code Online (Sandbox Code Playgroud)

好的 foo/build.gradle

dependencies {
    api 'com.example:widget:1.0.0'
}
Run Code Online (Sandbox Code Playgroud)

bar/build.gradle

dependencies {
    implementation project(path: ':foo')
}
Run Code Online (Sandbox Code Playgroud)

implementation 隐藏小部件依赖项。

api 使小部件依赖项具有可传递性。


/sf/answers/3114536561/

Gradle 文档

dependencies {
    api 'commons-httpclient:commons-httpclient:3.1'
    implementation 'org.apache.commons:commons-lang3:3.5'
}
Run Code Online (Sandbox Code Playgroud)

出现在api配置中的依赖项将传递给库的使用者,因此将出现在使用者的编译类路径上。

implementation另一方面,在配置中发现的依赖项不会暴露给消费者,因此不会泄漏到消费者的编译类路径中。这有几个好处:

  • 依赖不再泄漏到消费者的编译类路径中,因此您永远不会意外地依赖传递依赖
  • 由于减少了类路径大小,编译速度更快
  • 当实现依赖改变时更少的重新编译:消费者不需要重新编译
  • 更干净的发布:当与新的 maven-publish 插件结合使用时,Java 库会生成 POM 文件,这些文件可以准确地区分针对库进行编译所需的内容和在运行时使用库所需的内容(换句话说,不要混合编译库本身所需的内容和针对库进行编译所需的内容)。

compile 配置仍然存在,但不应使用,因为它不会提供apiimplementation 配置提供的保证。


Fra*_*oth 4

最后,问题不是来自脚本。我刚刚清除了 gradle 的缓存和每个项目的构建文件夹,以使其正常工作。

  • 在过去的 6 个小时里,我认真地花了 6 个小时试图让它发挥作用,而这就是缓存。应该先检查那里。谢谢! (3认同)