Wie sollte ich native Bibliotheken für JNI laden, um einen UnsatisfiedLinkError zu vermeiden?

Lesezeit: 3 Minuten

Benutzer-Avatar
gav

Ich möchte JNI unter Ubuntu 8.10 verwenden, mit Eclipse und gcc (dem Standard mit Ubuntu, wenn es Varianten gibt).

Ich kann meine Bibliothek anscheinend nicht laden, obwohl die Make-Datei sie erfolgreich erstellt hat.

Die wichtigste Java-Klasse ist wie folgt:

class Hello {
    public native void sayHello();

    static {
        System.loadLibrary("hello.so");
    }

    public static void main(String[] args) {
        Hello h = new Hello();
        h.sayHello();
    }
}

Meine Make-Datei ist als solche;

    all : hello.so

hello.so : Hello.o
    gcc -shared -o hello.so Hello.o

Hello.o : Hello.c Hello.h
    gcc -I/usr/lib/jvm/java-6-sun/include -I/usr/lib/jvm/java-6-sun/include/linux -c Hello.c -o Hello.o

Hello.h : Hello.class
    javah -jni Hello

clean :
    -del Hello.h
    -del Hello.o

Der Rest des Codes (Hello.c) sieht so aus, wie man es sich denken würde.

Der Fehler, den ich bekomme, ist wie folgt;

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello.so in java.library.path

Wenn ich einen expliziten Pfad verwende:

System.loadLibrary("/home/gavin/Work/workspace/JNI/hello.so");

Dann funktioniert es, aber ich würde lieber keinen expliziten Pfad verwenden, wenn möglich.

  • Vielen Dank für die Hilfe, Ihre Tipps waren alle richtig, mein mangelnder Ruf hindert mich daran, sie alle als hilfreich zu bezeichnen. Prost

    – gav

    28. Mai 2009 um 12:33 Uhr

  • Bitte folgen Sie diesem Link für weitere Details saurabhsharma123k.blogspot.in/2017/07/…

    – SAURABH_12

    4. Juli 2017 um 15:52 Uhr

Laut Pax sollten Sie den Bibliothekspfad dort einstellen, wo Java nach der Bibliothek suchen soll. Ihr Bibliotheksname sollte libhello.so lauten. Der Aufruf zum Laden der Bibliothek sollte dann lauten:

System.loadLibrary("hello");

Auf Linux-Bibliotheken wird durch die Konvention lib verwiesenName.so und basierend auf dem Namen geladen. Hier ist ein Verknüpfung über dynamische Verknüpfungsprobleme in Java aus der SWIG-Dokumentation, obwohl Sie SWIG nicht verwenden, ist dieser Abschnitt dennoch relevant.

  • Der Link ist in Ordnung, aber der Hinweis zur Verwendung von ‘-rpath’ ist falsch. Damit ‘rpath funktioniert, müsste es beim Kompilieren dieser virtuellen Java-Maschine selbst angegeben werden.

    – Kristian Spangsege

    11. Juni 2013 um 19:13 Uhr

Du rufst an System.loadLibrary() falsch. Das loadLibrary Die Methode nimmt einen Bibliotheksnamen, z. B. “hello”, und versucht, das entsprechende gemeinsam genutzte Objekt zu laden. Unter Unix wird versucht, “libhello.so” zu laden, und unter Windows wird versucht, “hello.dll” zu laden. Es wird erwartet, dass die Datei in gefunden wird java.library.path.

Die Methode, die Sie wahrscheinlich aufrufen möchten, ist System.load() die einen vollständig qualifizierten Dateinamen nimmt und lädt. Diese Methode sollte a dauern File als Argument, aber es nimmt stattdessen einen String. Wenn du benutzt loadmüssen Sie lokale Namenskonventionen manuell handhaben, aber Sie müssen sich nicht darauf verlassen java.library.path eingestellt werden.

Benutzer-Avatar
Nick

Mach Folgendes:

  1. Ändern Sie Ihre Java-Klasse wie folgt:

    class Hello {
    
        public native void sayHello();
    
        static {
            System.loadLibrary("hello");
        }
    
        public static void main(String[] args) {
            Hello h = new Hello();
            h.sayHello();
        }
    }
    
  2. benenne hello.so in libhello.so um:
    cp hello.so libhello.so oder mv hello.so libhello.so

  3. Rennen wie: java -Djava.library.path=/home/gavin/Work/workspace/JNI/ Hello

Und führen Sie es mit etwas wie:

java -Djava.library.path=/home/gavin/Work/workspace/JNI Hello

Sie müssen sicherstellen, dass das gemeinsam genutzte Objekt ist in Ihr Bibliothekspfad.

Benutzer-Avatar
Echo und Liebe

Betriebssystem: CentOS6.5. JNIHello.java:

public class JNIHello {
                static {
                                System.loadLibrary("JNIHello");
                }
                private native void sayHello();
                public static void main(String args[]) {
                                JNIHello jniHello = new JNIHello();
                                jniHello.sayHello();
                }
}

java home exportieren: export JAVA_HOME=/usr/java/jdk1.7.0_67-cloudera/

Java-Klasse kompilieren:

javac JNIHello.java

JNIHello.h generieren:

javah JNIHello

Implementieren Sie sayHello in JNIHello.c:

#include <jni.h>
#include <stdio.h>
#include "JNIHello.h"
/*
 * Class:     JNIHello
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNIHello_sayHello
  (JNIEnv *env, jobject obj) {
        printf("Hello world!\n");
        return;
}

Bibliothek kompilieren:

gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" JNIHello.c -fPIC -shared -o JNIHello.so

starte JNIHallo:

java -Djava.library.path=/home/ldp/caffe/test/ JNIHello
Hello world!

lib-Namensformat ref:

3.1.1. Shared Library Names

Jede gemeinsam genutzte Bibliothek hat einen speziellen Namen namens „Soname“. Der Soname hat die Präfix ‘lib’der Name der Bibliothek, die Phrase ‘.so’,

Ref-Link

1186570cookie-checkWie sollte ich native Bibliotheken für JNI laden, um einen UnsatisfiedLinkError zu vermeiden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy