如何在gradle中下载依赖项

65

我有一个自定义的编译任务。

task compileSpeedTest(type: JavaCompile) {
    classpath = files('build')
    source = fileTree('src/test/java/speed')
    destinationDir = file('bin')
}

在执行之前,Gradle不会尝试下载依赖项。 我找不到任何尝试这样做的任务名称,以便将其添加到dependsOn列表中。


你指的是哪些依赖关系?你的构建脚本没有定义任何依赖项。请添加相关代码,以便我们能够连接这些点。 - Benjamin Muschko
9个回答

63

如果您确实需要将Java依赖项下载到文件夹中,那么这是可能的。

例如:

apply plugin: 'java'

dependencies {
  runtime group: 'com.netflix.exhibitor', name: 'exhibitor-standalone', version: '1.5.2'
  runtime group: 'org.apache.zookeeper',  name: 'zookeeper', version: '3.4.6'
}

repositories { mavenCentral() }

task getDeps(type: Copy) {
  from sourceSets.main.runtimeClasspath
  into 'runtime/'
}

执行 gradle getDeps 命令时,将依赖项(及其依赖项)下载到 runtime 文件夹中。


已将此问题添加到Gradle的GitHub仓库: https://github.com/gradle/gradle/issues/14051 - Ihor Rybak

37

对于Intellij,前往View > Tool Windows > Gradle > Refresh All Projects(在Gradle窗口顶部的蓝色圆形箭头)进行刷新。

在此输入图片描述

9
我花了很长时间才明白这个。我认为“刷新”这个词非常反直觉,它并没有表明它会下载新的依赖项。在我看来,Maven的“install”更清晰易懂。 - Chris Neve
看起来是IDE集成问题。对我来说,刷新失败并出现Caused by: java.lang.NoClassDefFoundError: org/gradle/api/internal/plugins/DefaultConvention的错误。在Gitlab上使用Gradle的用户https://github.com/gradle/gradle/issues/11769表示,Intellij必须有实际版本才能使其正常工作。 - JeSa
或者是 mvn dependency:resolve,这个命令非常自解释。 - Dark Star1

25

9
下载似乎仅限于元信息(pom),而不是实际的jar文件(使用Gradle 6测试)。 - Johannes Barop
仅包含元信息,不包括任何单元测试依赖项。 - tosi

23

一项稍微轻松的任务,不会不必要地复制文件到目录中:

task downloadDependencies(type: Exec) {
    configurations.testRuntime.files
    commandLine 'echo', 'Downloaded all dependencies'
}

已更新至Kotlin和Gradle 6.2.0,并添加了buildscript依赖项解析:

fun Configuration.isDeprecated() = this is DeprecatableConfiguration && resolutionAlternatives != null

fun ConfigurationContainer.resolveAll() = this
  .filter { it.isCanBeResolved && !it.isDeprecated() }
  .forEach { it.resolve() }

tasks.register("downloadDependencies") {
  doLast {
    configurations.resolveAll()
    buildscript.configurations.resolveAll()
  }
}

4
我的理解是,Configuration.files 返回一个惰性求值的集合,其中包含指向本地 .gradle 缓存中依赖项的文件对象。如果你引用它,它将会检查它们是否存在,如果不存在,则会下载它们。 - Robert Elliot
2
如果您只是对缓存依赖项感兴趣,那么这非常完美。 - jfloff
如果您只是使用它来缓存存储库中的依赖项,则这具有额外的好处,即不需要生成上游配置中的工件。这在多项目构建中尤其相关,其中inputsdependsOn指令(包括Copy任务的from)将强制Gradle构建所有上游工件。当您只想下载依赖项时(而不一定要准备上游工件)时,这是一个完美的解决方案。谢谢。 - Mike Hill
1
似乎在Gradle 7+中,testRuntime应该改为runtimeClasspath - moffeltje

10

这个版本是在Robert Elliot的基础上构建的,但我并不完全确定它的功效。

// There are a few dependencies added by one of the Scala plugins that this cannot reach.
task downloadDependencies {
  description "Pre-downloads *most* dependencies"
  doLast {
    configurations.getAsMap().each { name, config ->
      println "Retrieving dependencies for $name"
      try {
        config.files
      } catch (e) {
        project.logger.info e.message // some cannot be resolved, silentlyish skip them
      }
    }
  }
}

我试图将其放入配置中而非操作中(通过删除 doLast),但这样做会破坏锌。我绕过了它,但最终结果与有或没有都是相同的。因此,我将其保留为显式状态。它似乎足够工作以减少稍后需要下载的依赖项,但在我的情况下无法消除它们。我认为其中一个Scala插件稍后添加了依赖项。


2
在Gradle 2.13上对我有用...需要这个来进行Dockerfized构建...谢谢! - Marcello DeSales

7
你应该试试这个:
task getDeps(type: Copy) {
    from configurations.runtime
    into 'runtime/'
}

我之前在一个项目中进行工作时,需要在自动化脚本中将所有依赖项下载到当前工作目录中。我猜您也在尝试实现类似的功能。

1

在 Robert Elliot 的回答基础上,进一步说明。如果出于某些原因,有人希望将 Gradle 缓存中的依赖项下载并复制到本地仓库(例如 Maven 的默认位置 ~/.m2/repository)中:

task downloadDependencies(type: Exec) {
    configurations.implementation.files + configurations.runtimeOnly.files
    finalizedBy "cacheToMavenLocal"
    commandLine "echo", "Downloaded all dependencies and copied to mavenLocal"
}

task cacheToMavenLocal(type: Copy) {
    from new File(gradle.gradleUserHomeDir, "caches/modules-2/files-2.1")
    into repositories.mavenLocal().url
    eachFile {
        List<String> parts = it.path.split("/")
        it.path = [parts[0].replace(".","/"), parts[1], parts[2], parts[4]].join("/")
    }
    includeEmptyDirs false
}

任务cacheToMavenLocal是从@Adrodoc55在Gradle论坛上的答案中复制并调整而来的


0

从问题中很难确定您想要做什么。我猜测您想要在Java插件提供的编译任务之外添加一个额外的编译任务。

最简单的方法可能是指定一个名为“speedTest”的新sourceSet。这将生成一个名为“speedTest”的configuration,您可以在其中使用dependencies块来指定依赖项。它还将为您生成一个名为compileSpeedTestJava的任务。

有关示例,请参阅defining new source setsJava plugin documentation

总的来说,似乎您对Gradle的依赖管理方式存在一些错误的假设。我建议您再次阅读用户指南中的“依赖管理”章节 :)


-9

没有下载依赖项的任务;它们是按需下载的。要了解如何使用Gradle管理依赖项,请参阅Gradle用户指南中的“第8章 依赖项管理基础知识”。


2
他们说Gradle像Ant一样灵活。 - Daniil Iaitskov
10
我读过《Gradle beyond the Basics》和《Building and Testing with Gradle》,但它们并没有对我有太大帮助,因为我无法触发下载依赖项的基本操作。许多页面都在谈论超级对象任务图和所有内容都是任务。而且没有一句话说获取依赖项不是一个任务。 - Daniil Iaitskov
1
我不同意这个负评。这个问题非常明显。我有一个Gradle任务。我已经提供了它。我正在寻找另一个任务将其添加到其依赖列表中。 - Daniil Iaitskov
1
我想问题很简单:如何确保对于依赖项相关的任务,依赖项确实被首先检索到。在我的情况下,我需要对检索到的构件执行一些后处理(将ZIP构件解压缩到工作树中),但是对于我的unzipDepenencies任务,简单的dependsOn: configurations.compile似乎行不通。如果我只是调用该任务,则如果它们不存在,则不会首先检索依赖项。换句话说:Gradle如何知道何时存在对依赖项的需求? - sschuberth
1
以下是一些关于为什么依赖 configurations.compile 不起作用的有趣阅读材料:链接地址 - sschuberth
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接