首页 文章

Gradle中最干净的方法是获取gradle依赖项缓存中jar文件的路径

提问于
浏览
31

我正在使用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

有一个更好的方法吗?

5 回答

  • 1

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

  • 0

    您还可以为工件创建专用配置,以保持其清洁;并使用 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
    }
    
  • 23

    我需要lombok.jar作为gwt构建的java构建标志,这非常有效!

    configurations { 
     lombok
    }
    dependencies {
      lombok 'org.projectlombok:lombok+'
    } 
    ext {
       lombok = configurations.lombok.asPath
    }
    
    compileGwt {
      jvmArgs "-javaagent:${lombok}=ECJ"
    }
    

    令我感到惊讶的是,该决议在配置阶段的早期工作得很早,但确实如此 .

  • 27

    我是这样做的:

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

    我最近也有这个问题 . 如果你正在构建一个java应用程序,手头的问题通常是想要获得 group:modulegroupId: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}")
                }
            }
    }
    

相关问题