/ / Dlaczego otrzymuję ten błąd Niezadowolony błąd z rodzimym kodem? - java, native

Dlaczego otrzymuję ten UnsatisfiedLinkError z natywnym kodem? - Java, ojczysty

Mam bibliotekę HelloWorld.so i program HelloWorld.java o następującej treści:

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, pojawia się ten błąd:

$ / usr / java1.4 / bin / java HelloWorld Wyjątek w wątku „głównym” java.lang.UnsatisfiedLinkError: brak HelloWorld w java.library.path at java.lang.ClassLoader.loadLibrary (ClassLoader.java:1491) at java.lang.Runtime.loadLibrary0 (Runtime.java:788) w java.lang.System.loadLibrary (System.java:834) w HelloWorld. <clinit> (HelloWorld.java:7)

Jakieś wskazówki?

Odpowiedzi:

11 dla odpowiedzi nr 1

Myślę, że niektóre punkty są pomocne przy otrzymywaniu tego błędu:

  1. Sprawdź spójność nazwy funkcji w Pliki .c i pliki generowane (.h)
  2. Nazwa biblioteki jni na podstawie systemu operacyjnego. Np .: w HelloWorld.java,System.loadLibrary("HelloWorld");
    • Solaris: libHelloWorld.so
    • Linux: libHelloWorld.so
    • Zdobyć: HelloWorld.dll
    • Prochowiec: libHelloWorld.jnilib
  3. Podczas uruchamiania dodaj -Djava.library.path=PATH. PATH do miejsca, w którym umieścisz bibliotekę jni

Oto moje odniesienie: https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni


9 dla odpowiedzi nr 2

Miałem ten problem i naprawiłem go, zmieniając nazwę mojej biblioteki na libHelloWorld.so i zgodnie z 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");
}
}

Budowa 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: put lib na początku nazwy pliku biblioteki


7 dla odpowiedzi nr 3

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

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

Edytować: Dan Dyer wskazuje, że zmienna środowiskowa LD_LIBRARY_PATH można do tego również użyć.


0 dla odpowiedzi nr 4

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

Nawet zanim to zrobiliśmy, próbowaliśmy użyć parametru „-D” i ustawić LD_LIBRARY_PATH, ale nie udało się.

Domyśl! :)

Dzięki jeszcze raz, Karen