【问题标题】:Why doesn't Gradle include transitive dependencies in compile / runtime classpath?为什么 Gradle 不在编译/运行时类路径中包含传递依赖项?
【发布时间】:2013-06-29 07:00:16
【问题描述】:

我正在学习 Gradle 的工作原理,但我不明白它如何解决项目传递依赖关系。

目前,我有两个项目:

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

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

我读过“lib 依赖项”,但它似乎只适用于here 所描述的本地项目,而不适用于外部依赖项。

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

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
        }
    }
}

这仅涉及项目A:

version = '1.0'
dependencies {
    compile 'com.company:X:1.0'
    compile 'com.company:B:1.0'
}

这是项目B使用的:

version = '1.0'
dependencies {
    compile ('com.company:projectA:1.0') {
        transitive = true
    }
}

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

【问题讨论】:

标签: build build-system dependency-management


【解决方案1】:

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

foo/build.gradle

dependencies {
    implementation 'com.example:widget:1.0.0'
}

foo/build.gradle

dependencies {
    api 'com.example:widget:1.0.0'
}

bar/build.gradle

dependencies {
    implementation project(path: ':foo')
}

implementation 隐藏小部件依赖项。

api 使小部件依赖传递。


来自https://stackoverflow.com/a/44493379/68086

来自Gradle documentation

dependencies {
    api 'commons-httpclient:commons-httpclient:3.1'
    implementation 'org.apache.commons:commons-lang3:3.5'
}

api 配置中出现的依赖项将是 传递给图书馆的消费者,因此将 出现在消费者的编译类路径中。

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

  • 依赖不再泄漏到消费者的编译类路径中,因此您永远不会意外依赖传递 依赖
  • 由于类路径大小减小,编译速度更快
  • 实现依赖关系发生变化时减少重新编译:消费者不需要重新编译
  • 更清洁的发布:与新的 maven-publish 插件结合使用时,Java 库会生成 POM 文件, 准确区分编译所需的内容 库以及在运行时使用该库需要什么(在其他 话,不要混合编译库本身需要什么和什么 需要针对库进行编译)。

编译配置仍然存在,但不应使用,因为它不能保证 apiimplementation 配置提供。

【讨论】:

  • 我有同样的问题,我使用的依赖项和你的一样,但是api 不会将其依赖项暴露给依赖项目,我在依赖项目中与implementation 配置一起使用.而 compile 在依赖项目中使用时按预期工作
  • 知道了,我有依赖项中定义的配置,一旦删除,它就成功了
【解决方案2】:

最后,问题不在于脚本。我刚刚清除了 gradle 的缓存和每个项目的构建文件夹,以使这项工作正常进行。

【讨论】:

  • 在过去的 6 个小时里认真地尝试让它工作,它是缓存。应该先检查那里。谢谢!
【解决方案3】:

将以下行放入projectB的依赖项中。

编译项目(':projectA')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 2015-03-12
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 2019-10-20
    相关资源
    最近更新 更多