/ / Pourquoi cette erreur UnsatisfiedLinkError est-elle générée avec du code natif? - java, natif

Pourquoi est-ce que j'obtiens cette erreur InsatisfiedLinkError avec le code natif? - java, natif

J'ai une bibliothèque appelée HelloWorld.so et un programme HelloWorld.java avec ce contenu:

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

Maintenant, quand j'essaye de lancer HelloWorld.java, j'obtiens cette erreur:

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

Des conseils?

Réponses:

11 pour la réponse № 1

Je pense que certains points sont utiles pour obtenir cette erreur:

  1. Vérifier la cohérence du nom de la fonction dans Fichiers .c et fichiers générés (.h)
  2. Nom de la bibliothèque jni basée sur le système d'exploitation. Ex: Dans HelloWorld.java,System.loadLibrary("HelloWorld");
    • Solaris: libHelloWorld.so
    • Linux: libHelloWorld.so
    • Gagner: HelloWorld.dll
    • Mac: libHelloWorld.jnilib
  3. Lors de l'exécution, ajoutez -Djava.library.path=PATH. PATH à l'endroit où vous mettez votre bibliothèque jni

Voici ma référence: https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni


9 pour la réponse № 2

J'ai eu ce problème et je l'ai corrigé en renommant ma bibliothèque en libHelloWorld.so et suivant la suggestion de Michael Myers. Je suis sur Arch Linux 64 bits.

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");
}
}

Construction et test:

$ 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 au début du nom de fichier de la bibliothèque


7 pour la réponse № 3

Où est situé HelloWorld.so? Vous devrez probablement spécifier son répertoire parent à l'aide du paramètre de ligne de commande. "-Djava.library.path".

Par exemple, si c'est dans "/path/libs/HelloWorld.so", ajouter -Djava.library.path=/path/libs en option lors de l'appel java. Par exemple, c’est "-Djava.library.path=lib" sur l'un de mes projets.

Modifier: Dan Dyer souligne que la variable d'environnement LD_LIBRARY_PATH peut également être utilisé pour cela.


0 pour la réponse № 4

@mmyers Merci d'avoir répondu. Nous avons découvert que tout ce que nous devions faire était de changer System.loadLibrary en System.load et de passer le chemin complet + nom de fichier en argument, fonctionnant comme un charme.

Même avant cela, nous avons essayé d’utiliser le paramètre "-D" et de définir LD_LIBRARY_PATH mais nous n’avons pas réussi.

Allez comprendre! :)

Merci encore, Karen