it-swarm.com.de

Die sauberste Methode in Gradle, um den Pfad zu einer JAR-Datei im Gradle-Abhängigkeitscache abzurufen

Ich benutze Gradle, um Hadoop-Aufgaben zu automatisieren. Wenn ich Hadoop aufrufe, muss ich in der Lage sein, den Pfad an einige Jars zu übergeben, von denen mein Code abhängt, damit Hadoop diese Abhängigkeit während der Karten-/Reduzierungsphase senden kann.

Ich habe etwas herausgefunden, das funktioniert, aber es fühlt sich chaotisch an und ich frage mich, ob es eine Funktion gibt, die ich irgendwo vermisse.

Dies ist eine vereinfachte Version meines Gradle-Skripts, die eine Abhängigkeit von der solr 3.5.0-JAR hat, und eine findSolrJar-Task, die alle JAR-Dateien in der Konfiguration durchläuft, um die richtige zu finden:

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

laufen diese gibt mir die Ausgabe wie folgt:

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

Gibt es einen besseren Weg, dies zu tun?

29
Ted Naleid

Ihr Code kann ein wenig vereinfacht werden, zum Beispiel project.configurations.compile.find { it.name.startsWith("solr-solrj-") }.

27

Sie können auch eine dedizierte Konfiguration für ein Artefakt erstellen, um es sauber zu halten. und verwenden Sie asPath, wenn die Tatsache, dass möglicherweise mehrere Speicherorte zurückgegeben werden können, für Ihren Anwendungsfall gut geeignet ist (dies geschieht, wenn dasselbe Jar an mehreren Speicherorten aufgelöst wird):

configurations {
  solr
}

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

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

Um das Kopieren und Einfügen zu vermeiden, können Sie diese spezielle Konfiguration in compile hinzufügen, falls Sie diese JAR-Datei auch in compile benötigen. Beispiel:

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

Ich brauchte lombok.jar als Java-Build-Flag, um gwt-Builds zu erstellen. Das hat großartig funktioniert!

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

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

Ich war überrascht, dass die Auflösung in der Konfigurationsphase früh genug funktioniert hat, aber es funktioniert.

2
DALDEI

So habe ich es gemacht:

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

Ich hatte vor kurzem auch dieses Problem. Wenn Sie eine Java-App erstellen, besteht das Problem normalerweise darin, dass Sie den group:module (groupId:artifactId) für die Zuordnung von Pfad zu Jar abrufen möchten (dh die Version ist kein Suchkriterium, da in einer App normalerweise nur eine Version von vorhanden ist) jedes spezifische Glas).

In meinem Gradle 5.1.1 (kotlin-basierten) Gradle Build habe ich dieses Problem gelöst mit:

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

Die Ausgabe würde ungefähr so ​​aussehen:

: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

Danach liegt es an Ihnen, etwas Nützliches mit diesem Mapzu tun. In meinem Fall füge ich meinem Java 11-Build einige --path-module-Optionen wie folgt hinzu:

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