2009-04-17 25 views
7

Mam biblioteki o nazwie HelloWorld.so i HelloWorld.java programu w tej treści:Dlaczego otrzymuję ten UnsatisfiedLinkError z natywnym kodem?

class HelloWorld { 
    private native void print(); 
    public static void main(String[] args) { 
     new HelloWorld().print(); 
    } 
    static { 
     System.loadLibrary("HelloWorld"); 
    } 
} 

Teraz, gdy próbuję uruchomić HelloWorld.java otrzymuję ten błąd:

 
$ /usr/java1.4/bin/java HelloWorld 
Exception in thread "main" 
java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path 
     at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491) 
     at java.lang.Runtime.loadLibrary0(Runtime.java:788) 
     at java.lang.System.loadLibrary(System.java:834) 
     at HelloWorld.<clinit>(HelloWorld.java:7) 

jakieś wskazówki ?

+0

Jeśli używasz systemu Linux (Ubuntu Terminal), to proszę spojrzeć na http://saurabhsharma123k.blogspot.in/2017 /07/java-jni-and-cc-from-command-line.html –

Odpowiedz

0

@mmyers Dziękujemy za odpowiedź. Dowiedzieliśmy się, że wszystko, co musieliśmy zrobić, to zmienić System.loadLibrary na System.load i przekazać pełną ścieżkę + nazwę pliku jako argument, działa jak urok.

Jeszcze zanim to zrobiliśmy, próbowaliśmy użyć parametru "-D" i ustawiliśmy LD_LIBRARY_PATH, ale nam się nie udało.

Idź! :)

Dzięki znowu Karen

+0

To niezmiernie dziwne. Biblioteka loadLibrary powinna zachowywać się identycznie, z tym wyjątkiem, że wymaga, aby biblioteka znajdowała się na ścieżce. Właśnie to ma pomóc -Djava.libary.path. –

+0

Nie wiem ... Chciałbym, żeby kiedyś ktoś mógł wyjaśnić :) – KNewton

+1

Nie działa dla mnie! –

7

Gdzie znajduje się HelloWorld.so? Prawdopodobnie musisz określić jego katalog macierzysty za pomocą parametru wiersza polecenia "-Djava.library.path".

Na przykład, jeśli jest w wersji "/path/libs/HelloWorld.so", dodaj -Djava.library.path=/path/libs jako opcję podczas wywoływania java. Na przykład jest to "-Djava.library.path=lib" w jednym z moich projektów.

Edytuj: Dan Dyer zwraca uwagę, że można do tego wykorzystać także zmienną środowiskową LD_LIBRARY_PATH.

+0

Czy rozszerzenie .so musi być jawnie określone również? – Otis

+0

Edytowane w celu wyjaśnienia (w rzeczywistości jest to ścieżka do folderu zawierającego plik .so). –

+0

@erickson: Dzięki, to wygląda lepiej. –

8

miałem ten problem i naprawić go przez zmianę nazwy moją bibliotekę do libHelloWorld.so i po sugestię Michaela Myersa. Jestem na Arch Linux 64-bit.

HelloWorld.c:

#include <jni.h> 
#include <stdio.h> 
#include "HelloWorld.h" 

/* shamelessly stolen from the book 'The Java Native Interface: Programmer's 
    Guide and Specification' */ 
JNIEXPORT void JNICALL 
Java_HelloWorld_print (JNIEnv *env, jobject obj) { 
    printf("Hello World!\n"); 
} 

HelloWorld.java:

class HelloWorld { 
    private native void print(); 
    public static void main(String[] args) { 
     new HelloWorld().print(); 
    } 
    static { 
     System.loadLibrary("HelloWorld"); 
    } 
} 

Budowanie i testowanie:

$ javac HelloWorld.java 
$ javah -classpath . HelloWorld 
$ gcc -shared -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux HelloWorld.c -o libHelloWorld.so 
$ java -classpath . -Djava.library.path=. HelloWorld 
Hello World! 

tl; dr: umieścić lib na początku nazwy pliku biblioteki

+1

tl; dr właśnie uratowałem mój dzień – serj

11

myślę niektóre punkty są pomocne, gdy otrzymuję ten błąd:

  1. Sprawdź spójność nazwy funkcji w .c plików i generowane pliki ( .h)
  2. Nazwa biblioteki JNI oparte na OS. Np .: W HelloWorld.Java, System.loadLibrary("HelloWorld");
    • Solaris: libHelloWorld.so
    • Linux: libHelloWorld.so
    • nagrodę: HelloWorld.dll
    • Mac: libHelloWorld.jnilib
  3. Podczas uruchamiania, dodaj -Djava.library.path=PATH. PATH na miejsce, gdzie można umieścić swój JNI biblioteki

Oto mój numer referencyjny: https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni

Powiązane problemy