Ich arbeite an einem Java-Projekt, das das JNI verwendet. Das JNI ruft eine benutzerdefinierte Bibliothek auf, die ich selbst geschrieben habe, sagen wir mylib.dll, und das hängt von einer Bibliothek eines Drittanbieters ab, libsndfile-1.dll.
Wenn ich mein Programm starte, stürzt es mit ab
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
Ich habe diese Site (und andere) durchsucht und eine Reihe von Korrekturen versucht:
Ich lief Dependency Walker. DW gab einige Warnungen aus - dass zwei von libsndfile benötigte Bibliotheken, MPR.DLL und SHLWAPI.DLL, "ungelöste Importe" hatten -, aber die DW-FAQ besagten, dass diese Warnungen sicher ignoriert werden könnten.
Ich habe die Methodennamen in mylib.dll korrigiert, wie hier vorgeschlagen . Die Methodennamen wurden vom Compiler irgendwie entstellt, aber ich habe Linker-Flags hinzugefügt und die Namen der DLL-Methoden stimmen jetzt genau mit denen in meiner JNI-Header-Datei überein.
Ich habe alle diese DLLs in dasselbe Verzeichnis gestellt - dasselbe Verzeichnis wie die .jar, die sie aufruft -, um sicherzustellen, dass sie sich auf dem richtigen Pfad befinden.
Kein Würfel.
Hat jemand eine Idee was los ist?
Ich mache meine Entwicklung in Visual Studio 2010 auf einem MacBook Pro (über Parallels). Ich teste in Windows XP auf einem Toshiba-Laptop.
Antworten:
Ich bin mir ziemlich sicher, dass der Klassenpfad und der Suchpfad für gemeinsam genutzte Bibliotheken wenig miteinander zu tun haben. Laut The JNI Book (das zugegebenermaßen alt ist) muss sich
java.library.path
die DLL unter Windows, wenn Sie die Systemeigenschaft nicht verwenden , im aktuellen Arbeitsverzeichnis oder in einem Verzeichnis befinden, das in der Windows-PATH
Umgebungsvariablen aufgeführt ist.Aktualisieren:
Anscheinend hat Oracle das PDF von seiner Website entfernt. Ich habe den obigen Link aktualisiert, um auf eine Instanz des PDF zu verweisen, das an der University of Texas - Arlington lebt.
Sie können auch die HTML-Version der JNI-Spezifikation von Oracle lesen . Das lebt im Java 8-Bereich der Java-Website und wird es hoffentlich noch eine Weile geben.
Update 2:
Zumindest in Java 8 (ich habe frühere Versionen nicht überprüft) können Sie Folgendes tun:
um den Suchpfad für die gemeinsam genutzte Bibliothek zu finden. Suchen Sie
java.library.path
in dieser Ausgabe nach dem Wert der Eigenschaft.quelle
CLASSPATH
wird überhaupt nicht verwendet. Ich bin mir auch nicht sicher, ob dascwd
überhaupt verwendet wird.java.library.path
oder wird einfachPATH
funktionieren. @dB ', der Ort, an dem du sie jetzt hast, ist falsch .Ich möchte diesen interessanten Fall informieren, nachdem alle oben genannten Methoden ausprobiert wurden, ist der Fehler immer noch da. Das Seltsame ist, dass es auf einem Windows 7-Computer funktioniert, unter Windows XP jedoch nicht. Dann benutze ich Dependency Walker und habe unter Windows XP festgestellt, dass es keine VC ++ Runtime als DLL-Anforderung gibt. Nach der Installation von VC ++ Runtime - Paket hier funktioniert es wie ein Zauber. Das, was mich gestört hat, ist, dass es immer wieder sagt, dass abhängige Bibliotheken nicht gefunden werden können, während intuitiv die JNI-abhängige DLL vorhanden ist. Es stellt sich jedoch schließlich heraus, dass die JNI-abhängige DLL eine andere abhängige DLL erfordert. Ich hoffe das hilft.
quelle
Sie müssen Ihre JNI-Bibliothek laden.
System.loadLibrary lädt die DLL aus dem JVM-Pfad (JDK-Bin-Pfad).
Wenn Sie eine explizite Datei mit einem Pfad laden möchten, verwenden Sie System.load ()
Siehe auch: Unterschied zwischen System.load () und System.loadLibrary in Java
quelle
Bitte überprüfen Sie, ob Ihr Bibliothekspfad richtig ist oder nicht. Natürlich können Sie folgenden Code verwenden, um den Pfad Ihres Bibliothekspfads zu überprüfen:
System.out.println(System.getProperty("java.library.path"));
Sie können den Pfad java.library.path beim Starten einer Java-Anwendung festlegen :
quelle
Wenn Sie eine 32-Bit-Version Ihrer DLL mit einer 64-Bit-JRE laden, kann dieses Problem auftreten. Das war mein Fall.
quelle
chromedriver.exe
der Selenium-Treiber für Chrome, der, soweit ich das beurteilen kann, nur in der 32-Bit-Version verfügbar ist.Hatte bei der Installation
javacv
undopencv
in Kombination mit Eclipse ein identisches Problem mit einem XP-Computer . Es stellte sich heraus, dass mir folgende Dateien fehlten:Sobald diese installiert waren, wurde das Projekt kompiliert und lief OK.
quelle
quelle
Ich habe einen großartigen Artikel von einigen Freunden bei keepsafe gefunden, der genau das durchgemacht hat, was ich getan habe. Es hat bei mir funktioniert, also hilft es dir hoffentlich auch! Lesen Sie, wenn Sie interessiert sind ( Die Gefahren beim Laden nativer Bibliotheken auf Android ) oder verwenden Sie es einfach
compile 'com.getkeepsafe.relinker:relinker:1.2.3'
und ersetzen
mit
quelle
Früher hatte ich genau das gleiche Problem und schließlich wurde es gelöst.
Ich habe alle abhängigen DLLs in demselben Ordner abgelegt, in dem mylib.dll gespeichert war, und habe sichergestellt, dass der JAVA-Compiler sie finden kann (wenn sich keine mylib.dll im Kompilierungspfad befindet, wird beim Kompilieren ein Fehler gemeldet). Das Wichtigste, was Sie beachten müssen, ist, dass Sie sicherstellen müssen, dass alle abhängigen Bibliotheken dieselbe Version wie mylib.dll haben. Wenn Ihre mylib.dll beispielsweise eine Release-Version ist, sollten Sie dort auch die Release-Version aller abhängigen Bibliotheken ablegen .
Hoffe, dies könnte anderen helfen, die auf das gleiche Problem gestoßen sind.
quelle
Ich hatte das gleiche Problem und habe alles versucht, was hier veröffentlicht ist, um es zu beheben, aber keines hat bei mir funktioniert. In meinem Fall verwende ich Cygwin, um die DLL zu kompilieren. Es scheint, dass JVM versucht, die JRE-DLLs im virtuellen Cygwin-Pfad zu finden. Ich habe den virtuellen Verzeichnispfad des Cygwin zu den DLLs von JRE hinzugefügt und es funktioniert jetzt. Ich habe so etwas gemacht wie:
quelle
In meiner Situation habe ich versucht, einen Java-Webdienst in Tomcat 7 über einen Connector in Eclipse auszuführen. Die App lief gut, als ich die Kriegsdatei auf einer Instanz von Tomcat 7 auf meinem Laptop bereitstellte. Die App benötigt einen JDBC-Typ-2-Treiber für "IBM DB2 9.5". Aus irgendeinem Grund konnte der Connector in Eclispe die Pfade in den IBM DB2-Umgebungsvariablen nicht sehen oder verwenden, um die auf meinem Laptop als jcc-Client installierten DLL-Dateien zu erreichen. In der Fehlermeldung wurde entweder angegeben, dass die DLL-Datei db2jcct2 nicht gefunden werden konnte, oder dass die abhängigen Bibliotheken für diese DLL-Datei nicht gefunden wurden. Letztendlich habe ich den Connector gelöscht und neu erstellt. Dann hat es richtig funktioniert. Ich füge diese Lösung hier als Dokumentation hinzu, da ich diese spezielle Lösung nirgendwo anders gefunden habe.
quelle
Das Erstellen einer statischen Bibliothek hat bei mir funktioniert und das Kompilieren mit
g++ -static
. Es bündelt die abhängigen Bibliotheken zusammen mit dem Build.quelle
Installation von Microsoft Visual C ++ 2010 SP1 Redistributable Es wurde behoben
quelle
Platzieren Sie die erforderlichen DLLs im Ordner und legen Sie den Ordnerpfad in der Umgebungsvariablen PATH fest. Stellen Sie sicher, dass die aktualisierte Umgebungs-PATH-Variable wiedergegeben wird.
quelle
Ich hatte das gleiche Problem mit der ffmpeg-Bibliothek, nachdem ich zwei Android-Projekte zu einem Projekt zusammengeführt hatte.
Das eigentliche Problem trat aufgrund von zwei verschiedenen Versionen der ffmpeg-Bibliothek auf, die jedoch mit denselben Namen im Speicher geladen wurden. Eine Bibliothek wurde in JNiLibs abgelegt, während sich die andere in einer anderen Bibliothek befand, die als Modul verwendet wurde. Ich konnte den Code des Moduls nicht ändern, da er schreibgeschützt war. Daher habe ich den in meinem eigenen Code verwendeten in ffmpegCamera umbenannt und ihn mit demselben Namen in den Speicher geladen.
Dies hat das Problem behoben und jetzt werden beide Versionen von Bibliotheken sowie separate Namen und Prozess-IDs im Speicher geladen.
quelle
Visual C++ Redistributable for VS2012
VSU_4\vcredist_x64.exe
oderVSU_4\vcredist_x84.exe
abhängig von Ihrer Systemkonfigurationdll
Dateienlib
zusammen mit Ihren anderen Bibliotheken (z\lib\win32-x86\your dll files
. B. ) in den Ordner .quelle