Jak naprawić UnsatisfiedLinkError (nie można znaleźć zależnych bibliotek) w projekcie JNI

Pracuję nad projektem Java, który używa JNI. JNI nazywa niestandardową bibliotekę, którą sam napisałem, powiedzmy mylib.dll, a to zależy od biblioteki 3rd party, libsndfile-1.dll.

Kiedy uruchamiam mój program zawiesza się z

java.lang.UnsatisfiedLinkError:  C:\...path...\mylib.dll: Can't find dependent libraries.

Przeszukałem tę stronę (i inne) i próbowałem kilku poprawek:

  1. Sprawdziłam dependency walker. DW dał kilka ostrzeżeń -- że dwie biblioteki wymagane przez libsndfile, MPR.DLL i SHLWAPI.DLL, miał "nierozwiązane importu" -- ale DW FAQ powiedział, że te ostrzeżenia mogą być bezpiecznie ignorowane.

  2. Naprawiłem nazwy metod w mylib.dll, zgodnie z sugestią tutaj . Nazwy metod zostały jakoś zniekształcone przez kompilator, ale dodałem flagi linkera i nazwy metod dll pasują teraz dokładnie do tych w moim pliku nagłówkowym jni.

  3. Umieściłem wszystkie te biblioteki DLL w tym samym katalogu -- tym samym katalogu co .słoik, który je nazywa-aby upewnić się, że są na właściwej drodze.

Nie ma mowy. Czy ktoś ma pojęcie o co chodzi? [1]}rozwijam się w Visual Studio 2010 na MacBooku pro (przez Parallels). Testuję w systemie Windows XP na laptopie toshiba.
Author: YCF_L, 2011-05-23

17 answers

Jestem prawie pewien, że ścieżka classpath i ścieżka wyszukiwania biblioteki współdzielonej mają ze sobą niewiele wspólnego. Zgodnie z Księgą JNI (która co prawda jest stara), w systemie Windows, jeśli nie używasz właściwości systemowej java.library.path, DLL musi znajdować się w bieżącym katalogu roboczym lub w katalogu wymienionym w zmiennej środowiskowej Windows PATH.


Update:

Wygląda na to, że Oracle usunęło plik PDF ze swojej strony internetowej. Zaktualizowałem powyższy link, aby wskazać na przykład PDF mieszka na University of Texas-Arlington.

Możesz również przeczytać HTML wersji specyfikacji JNI firmy Oracle . To mieszka w Java 8 sekcji strony Java i mam nadzieję, że będzie wokół przez jakiś czas.


Aktualizacja 2:

Przynajmniej w Javie 8 (nie sprawdzałem wcześniejszych wersji) możesz zrobić:

java -XshowSettings:properties -version

Aby znaleźć ścieżkę wyszukiwania biblioteki współdzielonej. Poszukaj wartości właściwości java.library.path w tym wyjściu.

 55
Author: QuantumMechanic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 21:33:36

Chcę poinformować o tym ciekawym przypadku, po wypróbowaniu wszystkich powyższych metod, błąd nadal istnieje. Dziwne jest to, że działa na komputerze z systemem Windows 7, ale na Windows XP tak nie jest. Następnie używam zależności walker i znaleźć na Windows XP nie ma VC++ Runtime jako moje wymagania dll. Po zainstalowaniu VC++ Runtime package tutaj działa jak urok. To, co mnie niepokoi, to to, że ciągle mówi, że nie można znaleźć zależnych bibliotek, podczas gdy intuicyjnie zależny od JNI dll jest tam jednak w końcu okazuje się, że zależna od JNI dll wymaga innego zależnego dl. Mam nadzieję, że to pomoże.

 19
Author: longbkit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-02 14:24:24

Musisz załadować bibliotekę JNI.

System.loadLibrary wczytuje bibliotekę DLL ze ścieżki JVM (JDK bin path).

Jeśli chcesz załadować jawny plik ze ścieżką, użyj System.załaduj()

Zobacz też: różnica między systemem.load () i System.loadLibrary in Java

 16
Author: Yochai Timmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:59

Proszę sprawdzić czy ścieżka do biblioteki jest prawidłowa czy nie. Oczywiście możesz użyć poniższego kodu, aby sprawdzić ścieżkę ścieżki biblioteki: System.out.println(System.getProperty("java.library.path"));

Możesz wyznaczyć Javę.biblioteka.path podczas uruchamiania aplikacji Java:

java -Djava.library.path=path ...
 6
Author: caopeng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-15 19:42:05

Jeśli załadujesz 32-bitową wersję dll z 64-bitowym JRE, możesz mieć ten problem. To była moja sprawa.

 5
Author: EFalco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-09 07:28:27

Miał identyczny problem z komputerem XP podczas instalacji javacv i opencv w połączeniu z Eclipse. Okazało się, że brakuje mi następujących plików:

    Msvcp100dll Msvcr100dll

Po ich zainstalowaniu, projekt skompilował się i działał OK.

 5
Author: Rob van Riswick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 21:30:05
  • Krótka odpowiedź: w przypadku błędu "nie mogę znaleźć zależnej biblioteki" sprawdź swoją $PATH (odpowiada punktowi #3 poniżej)
  • Długa odpowiedź:
    1. Pure java world: jvm używa" Classpath", aby znaleźć pliki klas
    2. JNI world (java/native boundary): jvm używa "java.biblioteka.path " (domyślnie $PATH), aby znaleźć biblioteki DLL
    3. pure native world: natywny kod używa $PATH do ładowania innych bibliotek DLL
 2
Author: user2038596,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-30 11:59:00

Znalazłem świetny artykuł znajomych z keepsafe, którzy przeszli przez to samo, co ja. Dla mnie to zadziałało, więc mam nadzieję, że to pomoże również Tobie! Przeczytaj, jeśli jesteś zainteresowany (niebezpieczeństwa ładowania natywnych bibliotek na Androida ) lub po prostu użyj

compile 'com.getkeepsafe.relinker:relinker:1.2.3'

I zastąp

System.loadLibrary("myLibrary");

Z

ReLinker.loadLibrary(context, "mylibrary");
 2
Author: rhysl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-14 15:17:48

Miałem dokładnie ten sam problem i w końcu został rozwiązany.

Umieszczam wszystkie zależne biblioteki DLL w tym samym folderze, w którym mylib.dll został zapisany i upewnij się, że kompilator JAVA może go znaleźć (jeśli nie ma mylib.dll w ścieżce kompilacji, pojawi się błąd zgłaszający to podczas kompilacji). Najważniejszą rzeczą, którą musisz zauważyć, jest upewnienie się, że wszystkie zależne biblioteki są tej samej wersji z mylib.dll, na przykład jeśli mylib.dll jest release version then powinieneś również umieścić tam wersję release wszystkich zależnych libów.

Mam nadzieję, że pomoże to innym, którzy napotkali ten sam problem.

 1
Author: Steven Peng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-09 09:09:28

Miałem ten sam problem i próbowałem wszystkiego, co jest tutaj napisane, aby go naprawić, ale żaden nie działał dla mnie. W moim przypadku używam Cygwin do kompilacji dll. Wydaje się, że JVM próbuje znaleźć biblioteki DLL JRE w wirtualnej ścieżce Cygwina. Dodałem ścieżkę wirtualnego katalogu Cygwina do bibliotek DLL JRE i działa teraz. Zrobiłem coś takiego:

SET PATH= "/cygdrive/C/Program Files / Java / jdk1.8.0_45"; % PATH %

 1
Author: estebanuri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-03 05:08:21

W mojej sytuacji próbowałem uruchomić usługę java web w Tomcat 7 poprzez złącze w Eclipse. Aplikacja działała dobrze, gdy wdrożyłem plik wojenny do instancji Tomcat 7 na moim laptopie. Aplikacja wymaga sterownika JDBC type 2 dla "IBM DB2 9.5". Z jakiegoś dziwnego powodu złącze w Eclispe nie mogło zobaczyć ani użyć ścieżek w zmiennych środowiskowych IBM DB2, aby dotrzeć do plików dll zainstalowanych na moim laptopie jako klient jcc. Komunikat o błędzie stwierdzał, że nie udało się znaleźć db2jcct2 pliku dll lub nie udało się znaleźć bibliotek zależnych dla tego pliku dll. Ostatecznie usunąłem złącze i przebudowałem je. Wtedy zadziałało prawidłowo. Dodaję To rozwiązanie tutaj jako dokumentację, ponieważ nie udało mi się znaleźć tego konkretnego rozwiązania nigdzie indziej.

 1
Author: bwfrieds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 16:31:36

Tworzenie statycznej biblioteki zadziałało na mnie, kompilowanie przy użyciu g++ -static. Łączy zależne biblioteki wraz z kompilacją.

 0
Author: Caesar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-28 14:20:41

Naprawiono instalację Microsoft Visual C++ 2010 SP1 Redistributable

 0
Author: Sunil Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-08 04:47:10

Umieść wymagane biblioteki DLL w folderze i ustaw ścieżkę do folderu w zmiennej środowiskowej PATH. upewnij się, że zaktualizowana zmienna ścieżki środowiska jest odzwierciedlona.

 0
Author: user3122472,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-19 05:33:46

Miałem ten sam problem z biblioteką ffmpeg po połączeniu dwóch projektów Androida jako jednego projektu.

Faktycznie problem pojawiał się z powodu dwóch różnych wersji biblioteki ffmpeg, ale były one ładowane z tymi samymi nazwami w pamięci. Jedna biblioteka została umieszczona w JNiLibs, podczas gdy druga znajdowała się wewnątrz innej biblioteki używanej jako moduł. Nie byĹ 'em w stanie zmodyfikowaÄ ‡ kodu MODUĹ' u, poniewaĹź byĹ 'on tylko odczytywany, wiÄ ™ c zmieniĹ' em nazwÄ ™ tego uĺźytego w moim kodzie na ffmpegCamera i wĹ 'adowaĺ' em go do pamiÄ ™ ci o tej samej nazwie.

System.loadLibrary("ffmpegCamera");

To rozwiązało problem i teraz obie wersje bibliotek ładują się dobrze jako oddzielna nazwa i identyfikator procesu w pamięci.

 0
Author: Mohsin Raza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-09 12:08:46

Podczas wywoływania System.loadLibrary(), JVM będzie szukał {[1] } dla Twojej natywnej biblioteki. Jeśli jednak ta biblioteka natywna deklaruje jakiekolwiek zależności od innych bibliotek natywnych, to system operacyjny będzie miał za zadanie znalezienie tych zależności natywnych bibliotek.

Ponieważ system operacyjny nie ma koncepcji java.library.path, nie będzie widział żadnych katalogów umieszczonych w Javie.biblioteka./ align = "left" / Zamiast tego będzie przeszukiwać tylko katalogi w zmiennej środowiskowej PATH systemu operacyjnego. To jest całkowicie w porządku, jeśli natywna Biblioteka jest natywną biblioteką systemu operacyjnego, ponieważ zostanie znaleziona na ścieżce. Jeśli jednak natywna zależność biblioteki jest natywną biblioteką utworzoną przez Ciebie lub kogoś innego, to nie zostanie ona znaleziona na ścieżce, chyba że ją tam umieścisz. To zachowanie jest dziwne, nieoczekiwane i niezbyt dobrze udokumentowane, ale jest udokumentowane w OpenJDK issue tracker tutaj . Możesz również znaleźć inną odpowiedź StackOverflow wzmacniającą to Wyjaśnienie, tutaj .

Masz kilka opcji. Możesz albo załadować każdą natywną bibliotekę w odpowiedniej kolejności zależności używając System.loadLibrary(), albo zmodyfikować ścieżkę tak, aby zawierała katalogi, w których przechowywane są Twoje natywne biblioteki.
 0
Author: Region39,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-17 20:26:04
  1. idź do http://tess4j.sourceforge.net/usage.html i kliknij na Visual C++ Redistributable for VS2012
  2. pobierz go i uruchom VSU_4\vcredist_x64.exe lub VSU_4\vcredist_x84.exe w zależności od konfiguracji systemu
  3. Umieść swoje pliki dll w folderze lib wraz z innymi bibliotekami(np \lib\win32-x86\your dll files).
 -2
Author: Pratik Varpe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-17 21:10:29