JNI HelloWorld java.lang.UnsatisfiedLinkError
Bonjour,
Je souhaite écrire un HelloWorld pour JNI, mais celui-ci ne fonctionne pas.
Voici l'arborescence de mon projet :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| .
+-- bin
| `-- test
| `-- TestJNI.class
+-- native
| +-- testjni.so
| +-- test_TestJNI.c
| +-- test_TestJNI.h
| `-- test_TestJNI.o
`-- src
`-- test
`-- TestJNI.java |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $ cat src/test/TestJNI.java
package test;
public class TestJNI {
static {
System.loadLibrary("testjni");
}
public static native void helloWorld();
public static void main(String... args) {
helloWorld();
}
} |
J'ai généré test_TestJNI.h grâce à la commande suivante :
Code:
javah -classpath bin -d native test.TestJNI
J'ai écrit mon fichier .c :
Code:
1 2 3 4 5 6 7 8
| $ cat native/test_TestJNI.c
#include <jni.h>
#include <stdio.h>
#include "test_TestJNI.h"
JNIEXPORT void JNICALL Java_test_TestJNI_helloWorld(JNIEnv * env, jclass class) {
printf("Hello world !\n");
} |
J'ai ensuite généré mon .so :
Code:
1 2 3 4
| $ cd native
$ gcc -fPIC -c test_TestJNI.c -o test_TestJNI.o -I/usr/lib/jvm/java-6-openjdk-amd64/include
$ gcc -shared -o testjni.so test_TestJNI.o
$ cd .. |
J'ai besoin de -fPIC car mon système est une 64bits, sans quoi j'ai l'erreur suivante :
Code:
relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
Donc à partir de là j'ai mon .so.
Je tente ensuite d'exécuter :
Code:
1 2 3 4 5 6
| $ java -Djava.library.path=native -cp bin test.TestJNI
Exception in thread "main" java.lang.UnsatisfiedLinkError: no testjni in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1681)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at test.TestJNI.<clinit>(TestJNI.java:6) |
Même problème avec :
Code:
$ java -Djava.library.path="$PWD/native"
(ou si je déplace mon .so à la racine du projet et que j'utilise -Djava.library.path=.)
Si je remplace dans TestJNI.java la ligne :
Code:
System.loadLibrary("testjni");
par :
Code:
System.load("/home/rom/java/TestJNI/native/testjni.so");
alors ça fonctionne.
Qu'ai-je mal fait ?
Merci de votre aide.