不满意的链接错误:java.library.path中没有库文件

我有这样的目录结构

. --compile_c.sh --compile_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 

当它具有在rtm_simple.c充实的native方法时,如何正确运行rtm_simple.c

目前,我已定义

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" 

我正试图跑

run.sh

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

哪里

compile_java.sh

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

compile_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}" 

(也试过java -Djava.library.path="$LD_LIBRARY_PATH:$libDir" -cp "${targetDir}:${libDir}/*" "${MainPackage}.${Main}"

产量

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

码:

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(String.format("successfully completed %d transactions and had to retry %d times",nofAborts)); } public static void main(String[] args) { System.loadLibrary("rtm_simple"); new SimpleJNITest().test(); } } 

(也尝试使用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; } 

如果要指定文件名,则需要使用System.load(String) ,而不是System.loadLibrary(String)方法。 loadLibrary以与平台相关的方式转换指定的名称。 在您的系统上,可能会添加一个lib前缀和.so后缀,但这意味着无论您如何调用loadLibrary ,它都无法加载名为rtm_simple.so的文件,即使它位于库搜索路径上也是如此。 或者换句话说,如果您确实想使用loadLibrary ,则需要将文件重命名为librtm_simple.so

如果在strace -fF下运行它,您可以看到JVM使用的路径。

建议您将System.loadLibrary()放在SimpleJNITest类的静态块中。 您可能需要在main中创建SimpleJNITest对象时更明确。

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