Pracuję nad projektem Java, który używa JNI. JNI wywołuje bibliotekę niestandardową, którą sam napisałem, powiedzmy mylib.dll, która zależy od biblioteki innej firmy, libsndfile-1.dll.
Kiedy uruchamiam program, ulega awarii z
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
Przeszukałem tę witrynę (i inne) i wypróbowałem kilka poprawek:
Pobiegłem chodzik dla uzależnień. DW przekazał kilka ostrzeżeń - że dwie biblioteki wymagane przez libsndfile, MPR.DLL i SHLWAPI.DLL, mają „nierozwiązane importy” - ale DW FAQ powiedział, że te ostrzeżenia można bezpiecznie zignorować.
Poprawiłem nazwy metod w mylib.dll, zgodnie z sugestią tutaj . Nazwy metod zostały w jakiś sposób zniekształcone przez kompilator, ale dodałem flagi konsolidatora i nazwy metod dll są teraz dokładnie zgodne z tymi w moim pliku nagłówkowym jni.
Umieściłem wszystkie te biblioteki DLL w tym samym katalogu - tym samym katalogu, co plik .jar, który je wywołuje - aby upewnić się, że znajdują się na właściwej ścieżce.
Nie ma kości.
Czy ktoś ma pojęcie o co chodzi?
Programuję w Visual Studio 2010 na MacBooku Pro (przez Parallels). Przeprowadzam testy w systemie Windows XP na laptopie Toshiba.
Odpowiedzi:
Jestem prawie pewien, że ścieżka klas i ścieżka wyszukiwania bibliotek współdzielonych mają ze sobą niewiele wspólnego. Zgodnie z The JNI Book (która wprawdzie jest stara), w systemie Windows, jeśli nie używasz
java.library.path
właściwości systemowej, biblioteka DLL musi znajdować się w bieżącym katalogu roboczym lub w katalogu wymienionym w systemie WindowsPATH
zmiennej środowiskowej .Aktualizacja:
Wygląda na to, że firma Oracle usunęła plik PDF ze swojej witryny internetowej. Zaktualizowałem powyższy link, aby wskazywał na przykład pliku PDF mieszkającego na Uniwersytecie Teksasu w Arlington.
Możesz także przeczytać wersję HTML specyfikacji JNI firmy Oracle . To znajduje się w sekcji Java 8 witryny Java i mam nadzieję, że będzie tam przez jakiś czas.
Aktualizacja 2:
Przynajmniej w Javie 8 (nie sprawdzałem wcześniejszych wersji) możesz:
aby znaleźć ścieżkę wyszukiwania bibliotek współdzielonych. Poszukaj wartości
java.library.path
właściwości w tych danych wyjściowych.źródło
CLASSPATH
w ogóle nie jest używany. Nie jestem też pewien, czycwd
w ogóle jest używany.java.library.path
lub po prostuPATH
zadziała. @dB ', miejsce, w którym je teraz masz, jest nieprawidłowe .Chcę poinformować o tym interesującym przypadku, po wypróbowaniu wszystkich powyższych metod błąd nadal występuje. Dziwne jest to, że działa na komputerze z systemem Windows 7, ale w systemie Windows XP nie. Następnie używam walkera zależności i stwierdziłem, że w systemie Windows XP nie ma VC ++ Runtime jako mojego wymagania dll. Po zainstalowaniu pakietu VC ++ Runtime tutaj działa jak urok. Przeszkadzało mi to, że ciągle powtarza Nie można znaleźć bibliotek zależnych, podczas gdy intuicyjnie istnieje biblioteka dll zależna od JNI, jednak ostatecznie okazuje się, że dll zależna od JNI wymaga innej biblioteki zależnej. Mam nadzieję, że to pomoże.
źródło
Musisz załadować swoją bibliotekę JNI.
System.loadLibrary ładuje bibliotekę DLL ze ścieżki JVM (ścieżka bin JDK).
Jeśli chcesz załadować jawny plik ze ścieżką, użyj System.load ()
Zobacz też: Różnica między System.load () i System.loadLibrary w Javie
źródło
Sprawdź, czy ścieżka do biblioteki jest prawidłowa, czy nie. Oczywiście możesz użyć następującego kodu, aby sprawdzić ścieżkę do biblioteki:
System.out.println(System.getProperty("java.library.path"));
Możesz wyznaczyć java.library.path podczas uruchamiania aplikacji Java:
źródło
Jeśli załadujesz 32-bitową wersję swojej biblioteki dll za pomocą 64-bitowego środowiska JRE, możesz mieć ten problem. To był mój przypadek.
źródło
chromedriver.exe
sterownik Selenium dla Chrome, który, o ile wiem, występuje tylko w wersji 32-bitowej.Miałem identyczny problem jak na komputerze XP podczas instalacji
javacv
iwopencv
połączeniu z Eclipse. Okazało się, że brakuje mi następujących plików:Po ich zainstalowaniu projekt został skompilowany i działał poprawnie.
źródło
źródło
Znalazłem świetny artykuł napisany przez znajomych z KeepSafe, który zawierał to samo, co ja. U mnie zadziałało, więc miejmy nadzieję, że Tobie też pomoże! 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 wymień
System.loadLibrary("myLibrary");
z
ReLinker.loadLibrary(context, "mylibrary");
źródło
Kiedyś miałem dokładnie ten sam problem i ostatecznie został rozwiązany.
Umieściłem wszystkie zależne biblioteki DLL w tym samym folderze, w którym był przechowywany mylib.dll i upewniłem się, że kompilator JAVA może go znaleźć (jeśli w ścieżce kompilacji nie ma mylib.dll, wystąpiłby błąd zgłaszający to podczas kompilacji). Ważną rzeczą na którą musisz zwrócić uwagę jest to, że musisz upewnić się, że wszystkie zależne biblioteki są w tej samej wersji co mylib.dll, na przykład jeśli twój mylib.dll jest wersją wydania, powinieneś również umieścić tam wydanie wszystkich bibliotek zależnych .
Mam nadzieję, że może to pomóc innym, którzy napotkali ten sam problem.
źródło
Miałem ten sam problem i próbowałem wszystkiego, co jest tutaj, aby go naprawić, ale nic nie działało. W moim przypadku używam Cygwin do kompilacji dll. Wygląda na to, że JVM próbuje znaleźć biblioteki DLL JRE w wirtualnej ścieżce Cygwin. Dodałem ścieżkę katalogu wirtualnego Cygwin do bibliotek DLL JRE i teraz działa. Zrobiłem coś takiego:
źródło
W mojej sytuacji próbowałem uruchomić usługę internetową java w Tomcat 7 przez złącze w Eclipse. Aplikacja działała dobrze, gdy wdrożyłem plik wojenny w instancji Tomcat 7 na moim laptopie. Aplikacja wymaga sterownika jdbc typu 2 dla „IBM DB2 9.5”. Z jakiegoś dziwnego powodu łącznik w Eclispe nie mógł zobaczyć lub użyć ścieżek w zmiennych środowiskowych IBM DB2, aby dotrzeć do plików dll zainstalowanych na moim laptopie jako klient jcc. W komunikacie o błędzie stwierdzono, że nie można znaleźć pliku dll db2jcct2 lub nie można znaleźć bibliotek zależnych dla tego pliku dll. Ostatecznie usunąłem złącze i odbudowałem je. Wtedy działało poprawnie. Dodam tutaj to rozwiązanie jako dokumentację, ponieważ nie udało mi się znaleźć tego konkretnego rozwiązania nigdzie indziej.
źródło
Stworzenie biblioteki statycznej zadziałało dla mnie, kompilacja przy użyciu
g++ -static
. Zawiera biblioteki zależne wraz z kompilacją.źródło
instalacja pakietu redystrybucyjnego Microsoft Visual C ++ 2010 SP1 Naprawiono to
źródło
umieść wymagane biblioteki DLL w folderze i ustaw ścieżkę folderu w zmiennej środowiskowej PATH. upewnij się, że zaktualizowana zmienna PATH środowiska jest odzwierciedlona.
źródło
Miałem ten sam problem z biblioteką ffmpeg po połączeniu dwóch projektów Androida jako jednego projektu.
Właściwie pojawił się problem z powodu dwóch różnych wersji biblioteki ffmpeg, ale zostały one załadowane do pamięci z tymi samymi nazwami. Jedna biblioteka została umieszczona w JNiLibs, a druga w innej bibliotece używanej jako moduł. Nie byłem w stanie zmodyfikować kodu modułu, ponieważ był on tylko do odczytu, więc zmieniłem nazwę używanego w moim kodzie na ffmpegCamera i zał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ę w pamięci, a także mają oddzielną nazwę i identyfikator procesu.
źródło
Dzwoniąc
System.loadLibrary()
JVM będzie patrzeć na plikjava.library.path
Twojej biblioteki natywnej. Jeśli jednak ta biblioteka natywna zadeklaruje jakiekolwiek zależności od innych bibliotek natywnych, system operacyjny będzie miał za zadanie znalezienie tych zależności bibliotek natywnych.Ponieważ system operacyjny nie ma pojęcia
java.library.path
, nie zobaczy żadnych katalogów umieszczonych w java.library.path. Zamiast tego przeszuka tylko katalogi w zmiennej środowiskowej PATH systemu operacyjnego. Jest to całkowicie w porządku, jeśli zależność biblioteki natywnej jest natywną biblioteką systemu operacyjnego, ponieważ zostanie znaleziona w PATH. Jeśli jednak zależność biblioteki natywnej jest biblioteką natywną utworzoną przez Ciebie lub kogoś innego, nie zostanie ona znaleziona w PATH, chyba że ją tam umieścisz. To zachowanie jest dziwne, nieoczekiwane i niezbyt dobrze udokumentowane, ale zostało udokumentowane w narzędziu do śledzenia problemów OpenJDK tutaj . Możesz również znaleźć inną odpowiedź StackOverflow wzmacniającą to wyjaśnienie, tutaj .Masz więc kilka opcji. Możesz albo załadować każdą bibliotekę natywną w prawidłowej kolejności zależności, używając
System.loadLibrary()
lub zmodyfikować PATH, aby uwzględnić katalogi, w których są przechowywane biblioteki natywne.źródło
Visual C++ Redistributable for VS2012
VSU_4\vcredist_x64.exe
lub wVSU_4\vcredist_x84.exe
zależności od konfiguracji systemudll
pliki wlib
folderze wraz z innymi bibliotekami (np\lib\win32-x86\your dll files
.).źródło