web-dev-qa-db-fra.com

Le moyen le plus propre dans Gradle pour obtenir le chemin d'accès à un fichier JAR dans le cache de dépendances Gradle

J'utilise Gradle pour aider à automatiser les tâches Hadoop. Lorsque j'appelle Hadoop, je dois pouvoir lui indiquer le chemin d'accès à certains fichiers jar dont dépend mon code afin que Hadoop puisse envoyer cette dépendance pendant la phase de mappage/réduction.

J'ai trouvé quelque chose qui fonctionne, mais ça semble en désordre et je me demande s'il y a une fonctionnalité qui me manque quelque part.

Il s'agit d'une version simplifiée de mon script Gradle qui dépend du fichier jar solr 3.5.0 et d'une tâche findSolrJar qui effectue une itération dans tous les fichiers jar de la configuration afin de trouver celui qui convient:

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

cela me donne une sortie comme ceci:

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

Y a-t-il une meilleure manière de faire cela?

29
Ted Naleid

Votre code peut être un peu simplifié, par exemple project.configurations.compile.find { it.name.startsWith("solr-solrj-") }.

27

Vous pouvez également créer une configuration dédiée pour un artefact, afin de le garder propre; et utilisez asPath si le fait qu'il puisse potentiellement renvoyer plusieurs emplacements fonctionne bien pour votre cas d'utilisation (cela se produit si le même fichier jar est résolu à plusieurs endroits):

configurations {
  solr
}

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

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

Pour éviter le copier-coller, au cas où vous auriez également besoin de ce fichier jar dans la configuration compile, vous pouvez ajouter cette configuration dédiée dans la variable compile, comme suit:

dependencies {
  solr 'org.Apache.solr:solr-solrj:3.5.0'
  compile configurations.solr.dependencies
}
21
Timur

J'avais besoin de lombok.jar en tant qu'indicateur de construction Java pour les constructions gwt, cela fonctionnait très bien!

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

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

J'ai été surpris que la résolution ait fonctionné suffisamment tôt dans la phase de configuration, mais c'est le cas.

2
DALDEI

Voici comment je l'ai fait:

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

J'ai récemment eu ce problème aussi. Si vous construisez une application Java, le problème est normalement que vous souhaitez obtenir le mappage group:module (groupId:artifactId) vers chemin-fichier (c'est-à-dire que la version n'est pas un critère de recherche, car dans une application, il n'y a normalement qu'une seule version de chaque pot spécifique).

Dans ma version 5.1.1 (à base de kotlin), j'ai résolu ce problème avec:

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

Le résultat serait un peu comme:

: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

Après cela, il vous appartient de faire quelque chose d’utile avec cette Map. Dans mon cas, j'ajoute quelques options --path-module à ma version de Java 11, comme ceci:

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}")
            }
        }
}
0
aanno