Wie füge ich der Datei build.gradle eine lokale Abhängigkeit von .jar-Dateien hinzu?

608

Daher habe ich versucht, meine lokale .jar-Dateiabhängigkeit zu meiner build.gradle-Datei hinzuzufügen:

apply plugin: 'java'

sourceSets {
    main {
        java {
            srcDir 'src/model'
        }
    }
}

dependencies {
    runtime files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
    runtime fileTree(dir: 'libs', include: '*.jar')
} 

Und Sie können sehen, dass ich die JAR-Dateien hier in den Ordner referencedLibraries eingefügt habe: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1/referencedLibraries

Das Problem ist jedoch, dass beim Ausführen des Befehls: gradle build in der Befehlszeile die folgende Fehlermeldung angezeigt wird:

error: package com.google.gson does not exist
import com.google.gson.Gson;

Hier ist mein gesamtes Repo: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1

Wang-Zhao-Liu QM
quelle
Sind Sie sicher, dass die Laufzeit nicht kompiliert wird? Dateien kompilieren (....)
Gabriele Mariotti
3
Es sieht so aus, als wäre es eine Kompilierungsabhängigkeit, wenn jar nicht erstellt werden kann. try: compile files ('libs / mnist-tools.jar', 'libs / gson-2.2.4.jar') Wenn Sie immer noch ein Problem haben, versuchen Sie es mit absoluten Pfaden, da dies ebenfalls problematisch sein könnte.
Patrz Jaka Franca
1
Diese Stapelüberlauffrage gab mir endlich die Antwort, die ich brauchte.
Craned

Antworten:

456

Wenn Sie diese .jar wirklich aus einem lokalen Verzeichnis nehmen müssen,

Fügen Sie neben Ihrem Modul gradle hinzu (nicht die App gradle-Datei):

repositories {
   flatDir {
       dirs 'libs'
   }
}


dependencies {
   implementation name: 'gson-2.2.4'
}

Warum versuchen Sie dies nicht, da Sie eine Standard-JAR-Datei in einem tatsächlichen Maven-Repository sind?

repositories {
   mavenCentral()
}
dependencies {
   implementation 'com.google.code.gson:gson:2.2.4'
}
Jorge_B
quelle
4
Ich habe genau danach gesucht, aber festgestellt, dass mein lokales Repository keine transitiven Abhängigkeiten auflöst (Gradle 2.7, Beispiel POM ist com.mojang: authlib: 1.5.21, extrahiert von minecraftforge.net)
Karl der Heide
1
Wenn Sie lokale JAR-Dateien in mehreren Verzeichnissen haben, müssen Sie alle zum flatDir hinzufügen. Beispiel: - flatDir {dirs 'libs1', 'libs2', 'libs3'}
Dhumil Agarwal
9
Ich habe eine gradle.buildDatei - Was ist diese "App-Gradle-Datei" und die "Modul-Gradle"?
Lealo
2
Gibt es eine Chance, dass jemand die Antwort mit einem Link zum offiziellen Abschnitt der Gradle-Dokumentation aktualisiert, in dem diese Funktionen beschrieben werden?
Misanthrop
2
implementation(":gson:2.2.4")scheint der Weg zu sein, es zu tun.
Eng.Fouad
697

Verwenden Sie gemäß der Dokumentation einen relativen Pfad für eine lokale JAR-Abhängigkeit wie folgt:

dependencies {
    implementation files('libs/something_local.jar')
}
Leeor
quelle
8
@ Gubatron es ist jetzt dokumentiert: gradle.org/docs/current/userguide/…
David Moles
7
Ich wollte nur hinzufügen, dass für diejenigen, die relative Pfade zu unserer JAR verwenden: Abhängigkeiten {Dateien kompilieren ("libs / Something_local.jar"} (dh doppelte Anführungszeichen, keine einfachen Anführungszeichen) von Groovy benötigt werden, um den Pfad zu bewerten. Zitate werden wörtlich in Groovy genommen.
specialk1st
Ich verwende also dasselbe und erhalte einen Kompilierungsfehler (es sieht so aus, als würde das Glas dort nicht gefunden.) Wenn ich einen absoluten Pfad gebe, funktioniert es einwandfrei.
RV_Dev
Ich würde diese Lösung bevorzugen, aber ich habe festgestellt, dass Gradle keinen Fehler ausgibt, wenn die Datei nicht vorhanden ist. Ich habe dies persönlich gefunden. Siehe diese SO-Frage für Details: stackoverflow.com/q/42527631/4851565
entpnerd
Ich habe einen ähnlichen Fehler erhalten, auch nachdem ich diese Lösung verwendet habe. Fehler Ich habe libs Ordner unter Apps nicht auf der gleichen Ebene wie Apps gelegt
Rishabh Dugar
314

Sie können dies auch tun, indem alle JARs in das lokale Repository aufgenommen werden. Auf diese Weise müssten Sie es nicht jedes Mal angeben.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}
Nachtwolf
quelle
3
Dies wird zum Kompilieren aller Jars im lib-Verzeichnis verwendet. Es ist die perfekte Lösung (y)
Sheraz Ahmad Khilji
1
... es sei denn, Sie möchten dieses libs-Verzeichnis für verschiedene Module mit unterschiedlichen Abhängigkeiten freigeben, z. B. keinen Servercode mit Clientcode einfügen oder mehr als eine Version einer Abhängigkeit in verschiedenen Untermodulen.
Ajax
Dies ist meine bevorzugte Implementierung gegenüber der akzeptierten Antwort, da hier ausdrücklich der Speicherort der Dateien angegeben ist. Dies ist nützlich, wenn Sie für einige Bibliotheken auf ein Repository wie mavenCentral und für andere auf lokale Kopien verweisen. In diesem Fall kann es zu einer Verzögerung kommen, während gradle in den anderen Repositorys nach den lokalen Bibliotheken sucht.
Satbot
1
Beachten Sie, dass dir auch ein absoluter Pfad sein kann. Auch anstelle von 'include' musste ich 'include' verwenden.
Eriel Marimon
53

Folgendes funktioniert für mich:

compile fileTree(dir: 'libs', include: '*.jar')

Siehe die Gradle-Dokumentation .

Mischa
quelle
6
Geniale Antwort, die einzige Lösung, die nach tagelanger Suche für mich funktioniert hat
Stardust
Es ist wichtig, sich daran zu erinnern, dass dies diese Methode ist. Wenn Sie nicht möchten, dass eine bestimmte Bibliothek mit Ihrem Projekt kompiliert wird, müssen Sie daran denken, sie aus dem libs-Ordner zu löschen. Ich mag diese Methode nicht, weil ich nicht sehe, welche Bibliothek i hinzugefügt, es sei denn, ich
betrete
1
Wie unterscheidet sich das von der Antwort von @ Nightwolf?
Trenton
2
Die Methode compile () für Argumente [Verzeichnis 'libs'] für ein Objekt vom Typ org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler
ieXcept
33

Sie können versuchen, Ihr lokales Maven-Repository für Gradle wiederzuverwenden:

  • Installieren Sie das Glas in Ihrem lokalen Maven-Repository:

    mvn install:install-file -Dfile=utility.jar -DgroupId=com.company -DartifactId=utility -Dversion=0.0.1 -Dpackaging=jar

  • Überprüfen Sie, ob Sie das JAR in Ihrem ~/.m2/lokalen Maven-Repository installiert haben

  • Aktivieren Sie Ihr lokales Maven-Repository in Ihrer build.gradleDatei:

    repositories {
      mavenCentral()  
      mavenLocal()  
    }
    
    dependencies {  
      implementation ("com.company:utility:0.0.1")  
    }
    • Jetzt sollte das JAR für die Implementierung in Ihrem Projekt aktiviert sein
Daniel Mora
quelle
Dieser hat mir geholfen, als alles andere fehlschlug!
User3
Während dies funktioniert, ist dies eine Problemumgehung und sollte nicht in automatisierten Produktions- / Bühnenumgebungen verwendet werden, da dies eine zusätzliche Abhängigkeit von einem .m2-Ordner (Maven-Installation) im Build-System hinzufügt.
saurav.varma
29

Die akzeptierte Antwort ist gut. Ich hätte jedoch verschiedene Bibliothekskonfigurationen in meinem Gradle-Build für mehrere Projekte benötigt, um dieselbe Java-Bibliothek eines Drittanbieters zu verwenden.

Das Hinzufügen von ' $ rootProject.projectDir ' zum Pfadelement ' dir ' in meinem Abschluss ' allprojects ' bedeutete, dass jedes Unterprojekt auf dasselbe ' libs' -Verzeichnis verwies und nicht auf eine lokale Version dieses Unterprojekts:

//gradle.build snippet
allprojects {
    ...

    repositories {
        //All sub-projects will now refer to the same 'libs' directory
        flatDir {
            dirs "$rootProject.projectDir/libs"
        }
        mavenCentral()
    }

    ...
}

BEARBEITEN von Quizzie: "$ {rootProject.projectDir}" wurde in "$ rootProject.projectDir" geändert (funktioniert in der neuesten Gradle-Version).

Big Rich
quelle
2
Aber wie verweise ich auf diesen libs-Ordner in der Datei build.gradle der Bibliothek? Jede Hilfe dazu.
Jeevs
1
Ändern Sie einfach "$ {rootProject.projectDir}" in "$ rootProject.projectDir", damit es wieder funktioniert.
Quizzie
4
Stellen Sie sicher, dass Sie doppelte Anführungszeichen anstelle von einfachen Anführungszeichen verwenden, da letztere nicht interpoliert werden.
FP frei
1
Dieser Ansatz hat mir geholfen.
Shreyash
1
Alle Antworten hier haben mir sehr geholfen. Dieses Muster verwenden wir und es erleichtert Mitarbeitern in Teams, JARs bei der Arbeit an Zweigen einfach in dieses Verzeichnis zu legen.
Lucy
12

Ein einfacher Weg, dies zu tun, ist

compile fileTree(include: ['*.jar'], dir: 'libs')

Es werden alle .jar-Dateien in Ihrem libs-Verzeichnis in App kompiliert.

ZygoteInit
quelle
Ist fileTree funktioniert für alle Unterverzeichnisse im libs-Ordner. Beispiel einige Gläser in der libs / sping / spring.jar, enthält sie in diesem Fall auch die spring .jar?
Mgr
Nein, das tut es nicht. Technisch sollte es nicht so gut sein, da wir die 'dir: libs' nicht Unterverzeichnisse von libs geben.
ZygoteInit
In diesem Fall, wie man alle Bibliotheken mit minimalen Aufgaben aus den Unterverzeichnissen
abruft
Hey @mallikgm Entschuldigung für die späte Antwort. Haben Sie versucht, einen Platzhalter in den Verzeichnispfad einzufügen, z. B. compile fileTree (einschließlich: [' .jar'], dir: 'libs ')
ZygoteInit
2
Wie unterscheidet sich das von der Antwort von @ Nightwolf?
Trenton
12

Eine Lösung für Benutzer von Kotlin DSL

Die bisher hinzugefügten Lösungen eignen sich hervorragend für das OP, können jedoch nicht mit Kotlin DSL verwendet werden, ohne sie zuvor zu übersetzen. Hier ist ein Beispiel, wie ich meinem Build mit Kotlin DSL eine lokale .JAR hinzugefügt habe:

dependencies {
    compile(files("/path/to/file.jar"))
    testCompile(files("/path/to/file.jar"))
    testCompile("junit", "junit", "4.12")
}

Denken Sie daran, dass bei Verwendung von Windows Ihre Backslashes maskiert werden müssen:

...
compile(files("C:\\path\\to\\file.jar"))
...

Denken Sie auch daran, dass Anführungszeichen doppelte Anführungszeichen und keine einfachen Anführungszeichen sein müssen.


Bearbeiten für 2020:

Gradle-Updates sind veraltet compileund testCompilezugunsten von implementationund testImplementation. Der obige Abhängigkeitsblock würde also für aktuelle Gradle-Versionen folgendermaßen aussehen:

dependencies {
    implementation(files("/path/to/file.jar"))
    testImplementation(files("/path/to/file.jar"))
    testImplementation("junit", "junit", "4.12")
}
Jonathan Landrum
quelle
1
+1 hat für mich gearbeitet! Wissen Sie, wie Sie dasselbe tun können, ohne die JAR-Datei erstellen zu müssen (falls ich das JAR zufällig erstellt habe)?
Kareem Jeiroudi
2
@KareemJeiroudi Ich verstehe Ihre Frage vielleicht falsch, aber wenn Sie darüber sprechen, ein Modul zu einer Abhängigkeit des Projekts zu machen, würden Sie compile(project(":MyProject"))ungefähr Folgendes tun : , wobei "MyProject" in Ihrer settings.gradleDatei mit etwas wie definiert ist include("MyProject").
Jonathan Landrum
8

Ich konnte den obigen Vorschlag unter https://stackoverflow.com/a/20956456/1019307 nicht zum Laufen bringen. Das hat aber bei mir funktioniert. Für eine Datei secondstring-20030401.jar, die ich in einem libs/Verzeichnis im Stammverzeichnis des Projekts gespeichert habe :

repositories {
    mavenCentral()
    // Not everything is available in a Maven/Gradle repository.  Use a local 'libs/' directory for these.
    flatDir {
       dirs 'libs'
   }
}

...

compile name: 'secondstring-20030401'
HankCa
quelle
Vielen Dank! Keine Ahnung warum, aber nur das hat bei mir funktioniert. Erstellte einen 'libs'-Ordner in meinem Projektstamm, schob die .jar-Datei hinein und kopierte Ihren' Kompilierungsnamen'-Eintrag. Natürlich hat auch die .jar-Erweiterung gelöscht.
anon58192932
Nein, das funktioniert mir nicht. Konnte nicht finden: miglayout-core:. An folgenden Orten gesucht: Datei: /user/path/to/miglayout-core.jar
Well Smith
Dies funktioniert, wenn Sie ein Dateiverzeichnis als Repository hinzufügen möchten: docs.gradle.org/current/userguide/…
Grubhart
7

Die Frage wurde bereits ausführlich beantwortet. Ich möchte noch etwas hinzufügen, das mir sehr überraschend erscheint:

Die Aufgabe "Gradle-Abhängigkeiten" listet keine Dateiabhängigkeiten auf. Auch wenn Sie vielleicht denken, dass sie doch im Block "Abhängigkeiten" angegeben wurden.

Verlassen Sie sich also nicht auf die Ausgabe, um zu überprüfen, ob Ihre referenzierten lokalen lib-Dateien ordnungsgemäß funktionieren.

icyerasor
quelle
6

Die Lösung, die für mich funktioniert hat, ist die Verwendung von fileTree in der Datei build.gradle. Behalten Sie die .jar-Datei, die als Abhängigkeit hinzugefügt werden muss, im libs-Ordner. Geben Sie den folgenden Code im Abhängigkeitsblock in build.gradle ein:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}
Jince Martin
quelle
5

Der beste Weg, dies zu tun, besteht darin, dies in Ihre build.gradle-Datei einzufügen und die Synchronisierungsoption zu drücken

dependency{
    compile files('path.jar')
}
Saunlogan
quelle
3

Sie können ein Glas hinzufügen, das tut:

Für gradle geben Sie einfach folgenden Code ein build.gradle:

dependencies {
...
compile fileTree(dir: 'lib', includes: ['suitetalk-*0.jar'])
...
}

und für Maven folgen Sie einfach den Schritten:

Für Intellij: Datei-> Projektstruktur-> Module-> Registerkarte Abhängigkeit-> Klicken Sie auf + Vorzeichen-> Glas und Abhängigkeit-> Wählen Sie die zu importierenden Gläser aus-> OK-> Anwenden (falls sichtbar) -> OK

Denken Sie daran, dass wenn Sie java.lang.NoClassDefFoundError: Could not initialize classzur Laufzeit eine Ausnahme haben, dies bedeutet, dass Abhängigkeiten in jar nicht dafür installiert sind, dass Sie alle Abhängigkeiten im übergeordneten Projekt hinzufügen müssen.

Ankit
quelle
0

Gehe zu Datei -> Projektstruktur -> Module -> App -> Registerkarte Abhängigkeiten -> Klicken Sie auf + (Schaltfläche) -> Dateiabhängigkeit auswählen -> JAR-Datei im lib-Ordner auswählen

Diese Schritte fügen Ihre Abhängigkeit automatisch zu gralde hinzu

Sehr einfach

Jaya
quelle
3
Ist das ein Pfad durch einige Java IDE-Menüs? Wahrscheinlich Idee?
Utgarda
1
Ja, das sieht nach etwas für IntelliJ IDEA aus, und ich denke nicht, dass es funktionieren wird. Oder es sieht so aus, als würde es funktionieren, bis eine Änderung am Gradle-Setup vorgenommen wird, die zu einer "Synchronisierung" führt, und die Synchronisierung erfolgt in eine Richtung von Gradle zu den IntelliJ-Einstellungen. Es synchronisiert nicht in die andere Richtung - zumindest glaube ich das nicht.
RenniePet
1
Wenn Sie den automatischen Import ausgewählt haben, wird die manuell importierte JAR-Datei bei der nächsten Änderung von entfernt build.gradle.
Jonathan Landrum
-1

Seien Sie vorsichtig, wenn Sie die kontinuierliche Integration verwenden. Sie müssen Ihre Bibliotheken auf demselben Pfad auf Ihrem Build-Server hinzufügen.

Aus diesem Grund möchte ich lieber jar zum lokalen Repository hinzufügen und dies natürlich auch auf dem Build-Server tun.

Akostha
quelle
-3

Ein anderer Weg:

Bibliothek in der Baumansicht hinzufügen. Klicken Sie mit der rechten Maustaste auf diesen. Wählen Sie das Menü "Als Bibliothek hinzufügen". Ein Dialogfeld wird angezeigt, in dem Sie das Modul auswählen können. OK und es ist geschafft.

YannXplorer
quelle