2009-04-17 11 views
7

que tienen una biblioteca llamada HelloWorld.so y una HelloWorld.java programa con este contenido:¿Por qué estoy obteniendo este UnsatisfiedLinkError con código nativo?

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

Ahora, cuando trato de ejecutar HelloWorld.java consigo este error:

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

Algún consejo ?

+0

Si su uso de Linux (terminal de Ubuntu), a continuación, por favor, eche un vistazo en http://saurabhsharma123k.blogspot.in/2017 /07/java-jni-and-cc-from-command-line.html –

Respuesta

0

@mmyers Gracias por responder. Descubrimos que todo lo que teníamos que hacer era cambiar System.loadLibrary a System.load y pasar la ruta completa + nombre de archivo como argumento, funcionó como un amuleto.

Incluso antes de hacerlo, tratamos de usar el parámetro "-D" y configurar LD_LIBRARY_PATH, pero no tuvimos éxito.

¡Ve a la figura! :)

Gracias de nuevo, Karen

+0

Eso es extremadamente extraño. loadLibrary debe comportarse de manera idéntica, excepto que requiere que la biblioteca esté en la ruta. ¿Con qué se supone que -Djava.libary.path ayuda? –

+0

No lo sé .... Me encantaría que algún día alguien pudiera explicar :) – KNewton

+1

¡No funcionó para mí! –

7

¿Dónde está HelloWorld.so? Probablemente necesite especificar su directorio principal utilizando el parámetro de línea de comandos "-Djava.library.path". Por ejemplo, si está en "/path/libs/HelloWorld.so", agregue -Djava.library.path=/path/libs como una opción al invocar java. Por ejemplo, es "-Djava.library.path=lib" en uno de mis proyectos.

Editar: Dan Dyer señala que la variable de entorno LD_LIBRARY_PATH también se puede utilizar para esto.

+0

¿También se debe indicar explícitamente la extensión .so? – Otis

+0

Editado para aclarar (en realidad es la ruta a la carpeta que contiene el archivo .so). –

+0

@erickson: Gracias, eso se ve mejor. –

8

que tenía este problema y lo arreglaron cambiando el nombre de mi biblioteca a libHelloWorld.so y siguiendo la sugerencia de Michael Myers. Estoy en 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"); 
    } 
} 

de construcción y pruebas:

$ 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: ponen lib al principio del nombre de archivo de la biblioteca

+1

tl; dr acaba de salvar mi día – serj

11

Creo que algunos puntos son útiles al conseguir este error:

  1. Comprobar la consistencia del nombre de función en archivos .c y genera archivos ( .h)
  2. Nombre de la biblioteca JNI basado en sistema operativo. Ejemplo: en HelloWorld.java, System.loadLibrary("HelloWorld");
    • Solaris: libHelloWorld.so
    • Linux: libHelloWorld.so
    • Win: HelloWorld.dll
    • Mac: libHelloWorld.jnilib
  3. Cuando se ejecuta, añadir -Djava.library.path=PATH. PATH al lugar donde pones tu biblioteca JNI

Aquí es mi referencia: https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni

Cuestiones relacionadas