2009-04-17 14 views
7

Ich habe eine Bibliothek mit dem Namen HelloWorld.so und ein Programm HelloWorld.java mit diesem Inhalt:Warum erhalte ich diesen UnbefriedigtenLinkError mit nativem Code?

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

Jetzt, wenn ich versuche HelloWorld.java ich diesen Fehler zu laufen:

 
$ /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) 

Irgendwelche Tipps ?

+0

Wenn Ihr mit Linux (Ubuntu-Terminal), dann haben Sie einen Blick auf http://saurabhsharma123k.blogspot.in/2017 /07/java-jni-and-cc-from-command-line.html –

Antwort

0

@mmyers Vielen Dank für Ihre Antwort. Wir fanden heraus, dass wir nur System.loadLibrary in System.load ändern mussten und den vollständigen Pfad + Dateiname als Argument übergeben mussten, was wie ein Zauber wirkte.

Schon vorher versuchten wir, den Parameter "-D" zu verwenden und LD_LIBRARY_PATH zu setzen, aber wir waren nicht erfolgreich.

Gehen Sie Abbildung! :)

Thanks again, Karen

+0

Das ist äußerst seltsam. LoadLibrary sollte sich identisch verhalten, außer dass die Bibliothek auf dem Pfad sein muss. Womit soll der -Djava.libary.path helfen? –

+0

Ich weiß es nicht .... Ich würde es lieben, wenn jemand irgendwann erklären könnte :) – KNewton

+1

Hat nicht funktioniert für mich! –

7

Wo befindet sich HelloWorld.so? Wahrscheinlich müssen Sie das übergeordnete Verzeichnis mit dem Befehlszeilenparameter "-Djava.library.path" angeben.

Wenn es beispielsweise in "/path/libs/HelloWorld.so" ist, fügen Sie -Djava.library.path=/path/libs als Option hinzu, wenn Sie java aufrufen. Zum Beispiel ist es "-Djava.library.path=lib" auf einem meiner Projekte.

Bearbeiten: Dan Dyer weist darauf hin, dass die Umgebungsvariable LD_LIBRARY_PATH auch dafür verwendet werden kann.

+0

Muss die .so-Erweiterung explizit angegeben werden? – Otis

+0

Bearbeitet, um zu klären (es ist eigentlich der Pfad zu dem Ordner, der die .so-Datei enthält). –

+0

@erickson: Danke, das sieht besser aus. –

8

hatte ich dieses Problem und reparierte es von meiner Bibliothek zu libHelloWorld.so Umbenennung und Michael Myers Vorschlag folgen. Ich bin auf 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"); 
    } 
} 

Bau und Prüfung:

$ 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 am Anfang des Dateinamens der Bibliothek

+1

tl; dr hat gerade meinen Tag gerettet – serj

11

Ich denke, einige Punkte hilfreich sind, wenn dieser Fehler:

  1. prüft Konsistenz von Funktionsnamen in .c Dateien und generierten Dateien ( .h)
  2. Namen der jni Bibliothek basierend auf OS. Beispiel: In HelloWorld.java, System.loadLibrary("HelloWorld");
    • Solaris: libHelloWorld.so
    • Linux: libHelloWorld.so
    • Win: HelloWorld.dll
    • Mac: libHelloWorld.jnilib
  3. Beim Laufen, fügen -Djava.library.path=PATH. PATH zu platzieren, wo Sie Ihre jni Bibliothek setzen

Hier ist meine Referenz: https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni

Verwandte Themen