Самый простой способ в Gradle получить путь к файлу jar в кэше зависимостей gradle - PullRequest
32 голосов
/ 06 марта 2012

Я использую Gradle, чтобы помочь автоматизировать задачи Hadoop. При вызове Hadoop мне нужно иметь возможность передать ему путь к некоторым jar-файлам, от которых зависит мой код, чтобы Hadoop мог отправлять эту зависимость во время фазы отображения / сокращения.

Я понял что-то, что работает, но мне кажется, что это грязно, и мне интересно, есть ли какая-то функция, которую я где-то упускаю.

Это упрощенная версия моего скрипта gradle, который зависит от jar solr 3.5.0 и задачи 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 ]

28 голосов
/ 06 марта 2012

Ваш код может быть немного упрощен, например project.configurations.compile.find { it.name.startsWith("solr-solrj-") }.

24 голосов
/ 24 сентября 2013

Вы также можете создать выделенную конфигурацию для артефакта, чтобы поддерживать его в чистоте;и используйте asPath, если тот факт, что он потенциально может вернуть несколько местоположений, хорошо работает для вашего варианта использования (происходит, если он разрешает один и тот же файл в нескольких местах):

configurations {
  solr
}

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

task findSolrJars() {
  println configurations.solr.asPath
}

Чтобы избежать копирования-вставки, в случаеВам также нужен этот jar в конфигурации compile, вы можете добавить эту выделенную конфигурацию в compile, например:

dependencies {
  solr 'org.apache.solr:solr-solrj:3.5.0'
  compile configurations.solr.dependencies
}
2 голосов
/ 26 августа 2016

Мне нужен был lombok.jar как флаг сборки java для сборки gwt, это отлично работает!

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

compileGwt {
  jvmArgs "-javaagent:${lombok}=ECJ"
}

Я был удивлен, что разрешение работало достаточно рано на этапе настройки, но это так.

1 голос
/ 11 апреля 2015

Вот как я это сделал:

project.buildscript.configurations.classpath.each {
    String jarName = it.getName();
    print jarName + ":"
}
0 голосов
/ 12 января 2019

У меня недавно тоже была эта проблема.Если вы создаете Java-приложение, проблема обычно заключается в том, что вы хотите получить group:module (groupId:artifactId) для сопоставления пути к банке (т. Е. Версия не является критерием поиска, поскольку в одном приложении обычно есть).только одна версия каждого конкретного jar).

В моей сборке gradle 5.1.1 (на основе kotlin) я решил эту проблему с помощью:

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.В моем случае я добавляю некоторые опции --path-module в мою сборку Java 11 следующим образом:

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}")
            }
        }
}
...