Erreur de lien insatisfait: pas de fichier de bibliothèque dans java.library.path

J’ai une structure de répertoire comme celle-ci

. --comstack_c.sh --comstack_java.sh --config.sh --execute_java.sh --run.sh --src --ccode --jnitest_SimpleJNITest.h --rtm_simple.c --jnitest --SimpleJNITest.java --lib --rtm_simple.so --classes --SimpleJNITest.class 

Comment exécuter correctement SimpleJNITest lorsque sa méthode native est rtm_simple.c dans rtm_simple.c ?

Actuellement, j’ai défini

config.sh

 targetDir="classes" libDir="lib" srcDir="src" MainPackage="jnitest" Main="SimpleJNITest" ccodeDir="ccode" cFileName="rtm_simple" jdkDir="/home/user/local/java/jdk1.7.0_65" mkdir -p "$targetDir" mkdir -p "$libDir" 

et j’essaye de courir

run.sh

 #!/bin/bash source comstack_java.sh javah -d "${srcDir}/${ccodeDir}" -cp "$targetDir" -jni "${MainPackage}.${Main}" source comstack_c.sh source execute_java.sh 

comstack_java.sh

 #!/bin/bash source config.sh javac -d "$targetDir" -sourcepath "$srcDir" -cp "${targetDir}:${libDir}/*" "${srcDir}/${MainPackage}/${Main}.java" 

comstack_c.sh

 #!/bin/bash source config.sh cFile="${srcDir}/${ccodeDir}/${cFileName}.c" soFile="${libDir}/${cFileName}.so" gcc -g -shared -fpic -I "${jdkDir}/include" -I "${jdkDir}/include/linux" $cFile -o $soFile 

execute_java.sh

 #!/bin/bash source config.sh export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${libDir}" java -cp "${targetDir}:${libDir}/*" "${MainPackage}.${Main}" 

(a également essayé java -Djava.library.path="$LD_LIBRARY_PATH:$libDir" -cp "${targetDir}:${libDir}/*" "${MainPackage}.${Main}" )

sortie

 $ ./run.sh Exception in thread "main" java.lang.UnsatisfiedLinkError: no rtm_simple in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) at java.lang.Runtime.loadLibrary0(Runtime.java:870) at java.lang.System.loadLibrary(System.java:1122) at jnitest.SimpleJNITest.main(SimpleJNITest.java:17) 

Code:

SimpleJNITest.java

 package jnitest; public class SimpleJNITest{ public static final int NOF_ITERATIONS = 100000; public native int nofAborts(int nofTransactions); public void test(){ int nofAborts = nofAborts(NOF_ITERATIONS); System.out.println(Ssortingng.format("successfully completed %d transactions and had to retry %d times",nofAborts)); } public static void main(Ssortingng[] args) { System.loadLibrary("rtm_simple"); new SimpleJNITest().test(); } } 

(a également essayé d’utiliser System.loadLibary("rtm_simple.so"); )

jnitest_SimpleJNITest.h

 /* DO NOT EDIT THIS FILE - it is machine generated */ #include  /* Header for class jnitest_SimpleJNITest */ #ifndef _Included_jnitest_SimpleJNITest #define _Included_jnitest_SimpleJNITest #ifdef __cplusplus extern "C" { #endif #undef jnitest_SimpleJNITest_NOF_ITERATIONS #define jnitest_SimpleJNITest_NOF_ITERATIONS 100000L /* * Class: jnitest_SimpleJNITest * Method: nofAborts * Signature: (I)I */ JNIEXPORT jint JNICALL Java_jnitest_SimpleJNITest_nofAborts (JNIEnv *, jobject, jint); #ifdef __cplusplus } #endif #endif 

rtm_simple.c

 #include  #include "jnitest_SimpleJNITest.h" JNIEXPORT jint JNICALL Java_jnitest_SimpleJNITest_nofAborts(JNIEnv* env, jobject obj, jint nof_iterations){ volatile int abort_counter = 0; volatile int i = 0; while (i  jump to local label 2*/ "1:\n\t" /*local label 1 (jumped to when transaction is aborted)*/ :"+rm"(abort_counter) /*artificial dependency*/ :"rm"(i) /*artificial dependency*/ ); ++abort_counter; __asm__ __volatile__ ( "2:" /*local label 2 (jumped to when transactoin is NOt aborted)*/ :"+rm"(abort_counter) /*artificial dependency*/ :"rm"(i) /*artificial dependency*/ ); } if(i != nof_iterations) return -1; return abort_counter; } 

Si vous souhaitez spécifier un nom de fichier, vous devez utiliser System.load(Ssortingng) et non la System.loadLibrary(Ssortingng) . loadLibrary transforme le nom spécifié d’une manière dépendant de la plate-forme. Sur votre système, un préfixe lib et un suffixe .so sont probablement ajoutés, mais cela signifie que, peu importe comment vous appelez loadLibrary , il ne pourra pas charger un fichier nommé rtm_simple.so même s’il se trouve dans le chemin de recherche de la bibliothèque. loadLibrary , si vous souhaitez utiliser loadLibrary , vous devez renommer le fichier librtm_simple.so .

Vous pouvez voir les chemins utilisés par la machine strace -fF si vous l’exécutez sous strace -fF .

Vous suggérons de placer votre System.loadLibrary () dans un bloc statique de la classe SimpleJNITest. Vous devrez peut-être être plus explicite lors de la création de l’object SimpleJNITest dans main.

 public class SimpleJNITest{ public static final int NOF_ITERATIONS = 100000; static { System.loadLibrary("rtm_simple"); }  public static void main(Ssortingng[] args) { SimpleJNITest simple = new SimpleJNITest(); simple.text(); } }