Damit dies System.loadLibrary()
funktioniert, muss sich die Bibliothek (unter Windows eine DLL) in einem Verzeichnis befinden, das sich irgendwo in Ihrem PATH
oder in einem Pfad befindet, der in der java.library.path
Systemeigenschaft aufgeführt ist (damit Sie Java wie starten können java -Djava.library.path=/path/to/dir
).
Außerdem loadLibrary()
geben Sie für den Basisnamen der Bibliothek ohne den .dll
am Ende an. Also, für /path/to/something.dll
, würden Sie nur verwenden System.loadLibrary("something")
.
Sie müssen sich auch genau ansehen UnsatisfiedLinkError
, was Sie bekommen. Wenn es so etwas sagt wie:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no foo in java.library.path
dann kann es die foo- Bibliothek (foo.dll) in Ihrem PATH
oder nicht finden java.library.path
. Wenn es so etwas sagt wie:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.example.program.ClassName.foo()V
Dann stimmt etwas mit der Bibliothek selbst nicht, da Java eine native Java-Funktion in Ihrer Anwendung nicht ihrem tatsächlichen nativen Gegenstück zuordnen kann.
Zunächst würde ich Ihren System.loadLibrary()
Anruf protokollieren, um zu sehen, ob dies ordnungsgemäß ausgeführt wird. Wenn es eine Ausnahme auslöst oder sich nicht in einem Codepfad befindet, der tatsächlich ausgeführt wird, erhalten Sie immer den UnsatisfiedLinkError
oben erläuterten letzteren Typ .
Als Nebenbemerkung stellen die meisten Benutzer ihre loadLibrary()
Aufrufe mit den nativen Methoden in einen statischen Initialisierungsblock in der Klasse, um sicherzustellen, dass er immer genau einmal ausgeführt wird:
class Foo {
static {
System.loadLibrary('foo');
}
public Foo() {
}
}
loadLibrary()
Bemerkung - sehr nützlich, wenn du keine Ahnung hast, was du falsch machst.lib
Präfix. AlsoSystem.loadLibrary("foo")
brauchtlibfoo.so
.Das Ändern der Variablen 'java.library.path' zur Laufzeit reicht nicht aus, da sie von JVM nur einmal gelesen wird. Sie müssen es wie folgt zurücksetzen:
Bitte machen Sie eine Beute unter: Ändern des Java-Bibliothekspfads zur Laufzeit .
quelle
Die ursprüngliche Antwort von Adam Batkin führt Sie zu einer Lösung. Wenn Sie jedoch Ihre Webanwendung erneut bereitstellen (ohne Ihren Webcontainer neu zu starten), sollte der folgende Fehler auftreten:
Dies liegt daran, dass der ClassLoader, der Ihre DLL ursprünglich geladen hat, weiterhin auf diese DLL verweist. Ihre Webanwendung wird jetzt jedoch mit einem neuen ClassLoader ausgeführt. Da dieselbe JVM ausgeführt wird und eine JVM nicht zwei Verweise auf dieselbe DLL zulässt, können Sie sie nicht neu laden . Daher kann Ihre Webanwendung nicht auf die vorhandene DLL zugreifen und keine neue laden. Also ... du steckst fest.
In der ClassLoader-Dokumentation von Tomcat wird erläutert, warum Ihre neu geladene Webanwendung in einem neuen isolierten ClassLoader ausgeführt wird und wie Sie diese Einschränkung umgehen können (auf sehr hohem Niveau).
Die Lösung besteht darin, die Lösung von Adam Batkin ein wenig zu erweitern:
Platzieren Sie dann ein Glas mit NUR dieser kompilierten Klasse im Ordner TOMCAT_HOME / lib.
Jetzt müssen Sie in Ihrer Webanwendung nur noch Tomcat zwingen, auf diese Klasse zu verweisen. Dies ist so einfach:
Jetzt sollte Ihre DLL im allgemeinen Klassenladeprogramm geladen sein und kann auch nach der erneuten Bereitstellung von Ihrer Webanwendung aus referenziert werden.
Sinn ergeben?
Eine funktionierende Referenzkopie finden Sie im Google-Code static-dll-bootstrapper .
quelle
Sie können verwenden
System.load()
einen absoluten Pfad angeben, der Ihren Wünschen entspricht, und nicht eine Datei im Standardbibliotheksordner für das jeweilige Betriebssystem.Wenn Sie native Anwendungen möchten, die bereits vorhanden sind, verwenden Sie
System.loadLibrary(String filename)
. Wenn Sie Ihre eigenen bereitstellen möchten, sind Sie wahrscheinlich besser mit load ().Sie sollten auch in der Lage sein,
loadLibrary
mit demjava.library.path
Set richtig zu arbeiten. SieheClassLoader.java
Implementierungsquelle, in der beide Pfade überprüft werden (OpenJDK)quelle
In dem Fall, in dem das Problem darin besteht, dass System.loadLibrary die betreffende DLL nicht finden kann, besteht ein häufiges Missverständnis (verstärkt durch Javas Fehlermeldung) darin, dass die Systemeigenschaft java.library.path die Antwort ist. Wenn Sie die Systemeigenschaft java.library.path auf das Verzeichnis setzen, in dem sich Ihre DLL befindet, findet System.loadLibrary tatsächlich Ihre DLL. Wenn Ihre DLL wiederum von anderen DLLs abhängt, wie dies häufig der Fall ist, kann java.library.path nicht helfen, da das Laden der abhängigen DLLs vollständig vom Betriebssystem verwaltet wird, das nichts von java.library weiß. Pfad. Daher ist es fast immer besser, java.library.path zu umgehen und das Verzeichnis Ihrer DLL vor dem Starten der JVM einfach zu LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (MacOS) oder Path (Windows) hinzuzufügen.
(Hinweis: Ich verwende den Begriff "DLL" im allgemeinen Sinne von DLL oder Shared Library.)
quelle
Wenn Sie eine Datei laden müssen, die sich auf ein Verzeichnis bezieht, in dem Sie sich bereits befinden (wie im aktuellen Verzeichnis), finden Sie hier eine einfache Lösung:
quelle
Für diejenigen, die suchen
java.lang.UnsatisfiedLinkError: no pdf_java in java.library.path
Ich stand vor der gleichen Ausnahme; Ich habe alles versucht und wichtige Dinge, damit es funktioniert, sind:
Es hat mit Tomcat 6 funktioniert.
quelle
Wenn Sie glauben, dass Sie einen Pfad der nativen Bibliothek hinzugefügt haben
%PATH%
, testen Sie mit:Es sollte Ihnen tatsächlich zeigen, ob Ihre DLL aktiviert ist
%PATH%
%PATH%
quelle
Ich armer ! verbrachte einen ganzen Tag dahinter. Schreiben Sie es hier auf, wenn jemand dieses Problem wiederholt.
Ich habe versucht zu laden, wie Adam es vorgeschlagen hatte, wurde dann aber mit der Ausnahme AMD64 vs IA 32 erwischt. Wenn Sie auf jeden Fall nach Adams (zweifellos die beste Wahl) Vorgehensweise gearbeitet haben, versuchen Sie, eine 64-Bit-Version des neuesten jre zu haben. Stellen Sie sicher Ihre JRE UND JDK sind 64-Bit und Sie haben sie korrekt zu Ihrem Klassenpfad hinzugefügt.
Mein Arbeitsbeispiel lautet hier: Unbefriedigter Linkfehler
quelle
Für Windows stellte ich fest, dass beim Laden der Füllungen (jd2xsx.dll ruft & ftd2xx.dll auf) in den Ordner windowws / system32 die Probleme behoben wurden. Ich hatte dann ein Problem mit meiner neueren fd2xx.dll, die mit Parametern zu tun hatte, weshalb ich die ältere Version dieser DLL laden musste. Ich werde das später herausfinden müssen.
Hinweis: Die Datei jd2xsx.dll ruft die Datei ftd2xx.dll auf, sodass das Festlegen des Pfads für die Datei jd2xx.dll möglicherweise nicht funktioniert.
quelle
Ich verwende Mac OS X Yosemite und Netbeans 8.02. Ich habe den gleichen Fehler erhalten und die einfache Lösung, die ich gefunden habe, ist wie oben. Dies ist nützlich, wenn Sie eine native Bibliothek in das Projekt aufnehmen müssen. Machen Sie das nächste für Netbeans:
Ich hoffe, es könnte für jemanden nützlich sein. Der Link, unter dem ich die Lösung gefunden habe, ist hier: java.library.path - Was ist das und wie wird es verwendet?
quelle
VM Options: java -Djava.library.path="your_path"
Ich hatte das gleiche Problem und der Fehler war auf eine Umbenennung der DLL zurückzuführen. Es kann vorkommen, dass der Bibliotheksname auch irgendwo in der DLL geschrieben ist. Als ich seinen ursprünglichen Namen zurücklegte, konnte ich mit laden
System.loadLibrary
quelle
Es ist einfach, einfach java -XshowSettings: properties in Ihre Befehlszeile in Windows zu schreiben und dann alle Dateien in den von java.library.path angezeigten Pfad einzufügen.
quelle