Gradle 中获取 gradle 依赖项缓存中 jar 文件路径的最简洁方法

Posted

技术标签:

【中文标题】Gradle 中获取 gradle 依赖项缓存中 jar 文件路径的最简洁方法【英文标题】:Cleanest way in Gradle to get the path to a jar file in the gradle dependency cache 【发布时间】:2012-03-23 14:10:46 【问题描述】:

我正在使用 Gradle 来帮助自动化 Hadoop 任务。调用 Hadoop 时,我需要能够将路径传递给我的代码所依赖的一些 jar,以便 Hadoop 可以在 map/reduce 阶段发送该依赖。

我想出了一些可行的方法,但感觉很乱,我想知道我是否在某个地方缺少某个功能。

这是我的 gradle 脚本的简化版本,它依赖于 solr 3.5.0 jar,以及一个 findSolrJar 任务,它遍历配置中的所有 jar 文件以找到正确的:

apply plugin: 'groovy'

repositories 
    mavenCentral()


dependencies 
    compile 'org.apache.solr:solr-solrj:3.5.0'


task findSolrJar() 
     println project.configurations.compile*.toURI().find  URI uri -> new File(uri).name == 'solr-solrj-3.5.0.jar'

运行它会给我这样的输出:

gradle findSolrJar                                                                                                                                                                                                                                                           
file:/Users/tnaleid/.gradle/caches/artifacts-8/filestore/org.apache.solr/solr-solrj/3.5.0/jar/74cd28347239b64fcfc8c67c540d7a7179c926de/solr-solrj-3.5.0.jar
:findSolrJar UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.248 secs

有没有更好的方法来做到这一点?

【问题讨论】:

【参考方案1】:

您的代码可以稍微简化一下,例如project.configurations.compile.find it.name.startsWith("solr-solrj-")

【讨论】:

【参考方案2】:

您还可以为工件创建专用配置,以保持其干净;并使用 asPath 如果它可能返回多个位置这一事实适用于您的用例(如果它在多个位置解析相同的 jar,则会发生这种情况):

configurations 
  solr


dependencies 
  solr 'org.apache.solr:solr-solrj:3.5.0'


task findSolrJars() 
  println configurations.solr.asPath

为避免复制粘贴,如果您还需要 compile 配置中的那个 jar,您可以将此专用配置添加到 compile 之一中,例如:

dependencies 
  solr 'org.apache.solr:solr-solrj:3.5.0'
  compile configurations.solr.dependencies

【讨论】:

【参考方案3】:

我是这样做的:

project.buildscript.configurations.classpath.each 
    String jarName = it.getName();
    print jarName + ":"

【讨论】:

顺便说一句,':' 在 Windows 上不起作用。使用File.pathSeparator 可以解决这个问题。【参考方案4】:

我需要 lombok.jar 作为 gwt 构建的 java 构建标志,这很好用!

configurations  
 lombok

dependencies 
  lombok 'org.projectlombok:lombok+'
 
ext 
   lombok = configurations.lombok.asPath


compileGwt 
  jvmArgs "-javaagent:$lombok=ECJ"

我很惊讶该解决方案在配置阶段足够早地起作用,但确实如此。

【讨论】:

【参考方案5】:

我最近也遇到了这个问题。如果您正在构建一个 java 应用程序,手头的问题通常是想要将group:module (groupId:artifactId) 映射到路径到 jar 映射(即版本不是搜索条件,因为在一个应用程序中通常有每个特定 jar 仅一个版本)。

在我的 gradle 5.1.1(基于 kotlin)的 gradle 构建中,我解决了这个问题:

var spec2File: Map<String, File> = emptyMap()
configurations.compileClasspath 
    val s2f: MutableMap<ResolvedModuleVersion, File> = mutableMapOf()
    // https://discuss.gradle.org/t/map-dependency-instances-to-file-s-when-iterating-through-a-configuration/7158
    resolvedConfiguration.resolvedArtifacts.forEach( ra: ResolvedArtifact ->
        s2f.put(ra.moduleVersion, ra.file)
    )
    spec2File = s2f.mapKeys("$it.key.id.group:$it.key.id.name")
    spec2File.keys.sorted().forEach( it -> println(it.toString() + " -> " + spec2File.get(it)))

输出会是这样的:

:jing -> /home/tpasch/scm/db-toolchain/submodules/jing-trang/build/jing.jar
:prince -> /home/tpasch/scm/db-toolchain/lib/prince-java/lib/prince.jar
com.github.jnr:jffi -> /home/tpasch/.gradle/caches/modules-2/files-2.1/com.github.jnr/jffi/1.2.18/fb54851e631ff91651762587bc3c61a407d328df/jffi-1.2.18-native.jar
com.github.jnr:jnr-constants -> /home/tpasch/.gradle/caches/modules-2/files-2.1/com.github.jnr/jnr-constants/0.9.12/cb3bcb39040951bc78a540a019573eaedfc8fb81/jnr-constants-0.9.12.jar
com.github.jnr:jnr-enxio -> /home/tpasch/.gradle/caches/modules-2/files-2.1/com.github.jnr/jnr-enxio/0.19/c7664aa74f424748b513619d71141a249fb74e3e/jnr-enxio-0.19.jar

之后,您可以使用此Map 做一些有用的事情。就我而言,我向我的 Java 11 构建添加了一些 --path-module 选项,如下所示:

val patchModule = listOf(
        "--patch-module", "commons.logging=" +
        spec2File["org.slf4j:jcl-over-slf4j"].toString(),

        "--patch-module", "org.apache.commons.logging=" +
        spec2File["org.slf4j:jcl-over-slf4j"].toString()
)
patchModule.forEach(it -> println(it))

tasks 
        withType<JavaCompile> 
            doFirst 
                options.compilerArgs.addAll(listOf(
                        "--release", "11",
                        "--module-path", classpath.asPath
                ) + patchModule)
                // println("Args for for $name are $options.allCompilerArgs")
            
        

【讨论】:

以上是关于Gradle 中获取 gradle 依赖项缓存中 jar 文件路径的最简洁方法的主要内容,如果未能解决你的问题,请参考以下文章

Gradle 将依赖项下载到缓存而不是 Maven 存储库

Gradle离线如何缓存依赖项

使用 Gradle build 在 IntelliJ IDEA 中获取 Gradle 依赖项

如何在 gradle 中获取依赖项的元数据?

从 Gradle v7+ 获取版本目录中所有依赖项的列表

Gradle - 获取依赖项的 URL