Es ist möglich, eine einzelne JAR-Datei mit allen Abhängigkeiten einschließlich der nativen JNI-Bibliotheken für eine oder mehrere Plattformen zu erstellen. Der grundlegende Mechanismus besteht darin, System.load (Datei) zum Laden der Bibliothek anstelle der typischen System.loadLibrary (String) zu verwenden, die die Systemeigenschaft java.library.path durchsucht. Diese Methode vereinfacht die Installation erheblich, da der Benutzer die JNI-Bibliothek nicht auf seinem System installieren muss, jedoch auf Kosten der Tatsache, dass möglicherweise nicht alle Plattformen unterstützt werden, da die spezifische Bibliothek für eine Plattform möglicherweise nicht in der einzelnen JAR-Datei enthalten ist .
Der Prozess ist wie folgt:
- Fügen Sie die nativen JNI-Bibliotheken an einem plattformspezifischen Speicherort in die JAR-Datei ein, z. B. unter NATIVE / $ {os.arch} / $ {os.name} /libname.lib
- Erstellen Sie Code in einem statischen Initialisierer der Hauptklasse zu
- Berechnen Sie den aktuellen os.arch und os.name
- Suchen Sie mit Class.getResource (String) in der JAR-Datei am vordefinierten Speicherort nach der Bibliothek.
- Wenn es existiert, extrahieren Sie es in eine temporäre Datei und laden Sie es mit System.load (Datei).
Ich habe Funktionen hinzugefügt, um dies für jzmq, die Java-Bindungen von ZeroMQ (schamloser Plug), zu tun. Den Code finden Sie hier . Der jzmq-Code verwendet eine Hybridlösung. Wenn eine eingebettete Bibliothek nicht geladen werden kann, sucht der Code wieder nach der JNI-Bibliothek im Pfad java.library.path.
UnsatisfiedLinkError
als Laden der ersteren DLL will implizit die letztere laden, kann sie aber nicht finden, da sie im Glas versteckt ist. Auch das erstmalige Laden der letzteren DLL hilft nicht.DLL
müssen im Voraus bekannt sein und ihre Standorte sollten in derPATH
Umgebungsvariablen hinzugefügt werden.https://www.adamheinrich.com/blog/2012/12/how-to-load-native-jni-library-from-jar/
ist ein großartiger Artikel, der mein Problem löst.
In meinem Fall habe ich den folgenden Code zum Initialisieren der Bibliothek:
quelle
Schauen Sie sich One-JAR an . Es wird Ihre Anwendung in einer einzigen JAR-Datei mit einem speziellen Klassenladeprogramm zusammenfassen, das unter anderem "Jars in Jars" verarbeitet.
Es verarbeitet native (JNI) Bibliotheken, indem es sie nach Bedarf in einen temporären Arbeitsordner entpackt.
(Haftungsausschluss: Ich habe One-JAR noch nie verwendet, musste es noch nicht, habe es nur für einen regnerischen Tag mit einem Lesezeichen versehen.)
quelle
1) Fügen Sie die native Bibliothek als Ressource in Ihre JAR ein. Z.B. Fügen Sie mit Maven oder Gradle und dem Standardprojektlayout die native Bibliothek ein
main/resources
Verzeichnis.2) Geben Sie den Code in statischen Initialisierern von Java-Klassen, die sich auf diese Bibliothek beziehen, wie folgt ein:
quelle
JarClassLoader ist ein Klassenladeprogramm zum Laden von Klassen, nativen Bibliotheken und Ressourcen aus einer einzelnen Monster-JAR und aus JARs innerhalb der Monster-JAR.
quelle
Wahrscheinlich müssen Sie die native Bibliothek vom lokalen Dateisystem trennen. Soweit ich weiß, befasst sich der Code, der das native Laden ausführt, mit dem Dateisystem.
Dieser Code soll Ihnen den Einstieg erleichtern (ich habe ihn eine Weile nicht mehr angeschaut und er dient einem anderen Zweck, sollte aber den Trick machen, und ich bin im Moment ziemlich beschäftigt, aber wenn Sie Fragen haben, hinterlassen Sie einfach einen Kommentar und ich werde so schnell wie möglich antworten.
quelle