[英]Unsatisfied link error: no library file in 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
如何正確運行SimpleJNITest
當其具有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 <jni.h>
/* 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 <jni.h>
#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 < nof_iterations) {
__asm__ __volatile__ (
"xbegin 1f" /*1f: local label 1, look forward to find first*/
:"+rm"(i) /*artificial dependency to prevent re-ordering*/
);
++i;
__asm__ __volatile__ (
"xend\n\t"
"jmp 2f\n" /*not aborted ==> 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,則可以看到JVM使用的路徑。
建議您將System.loadLibrary()放在SimpleJNITest類的靜態塊中。 您可能需要在main中創建SimpleJNITest對象來使其更加明確。
public class SimpleJNITest{
public static final int NOF_ITERATIONS = 100000;
static {
System.loadLibrary("rtm_simple");
}
<blah blah blah>
public static void main(String[] args) {
SimpleJNITest simple = new SimpleJNITest();
simple.text();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.