Intereting Posts
Objective-C Runtime: что добавить для размера и выравнивания для class_addIvar? Периодическая нить не работает в режиме реального времени в Xenomai Летучие семантики в C99 Вывод программы строки C Бит-операции в C scanf не работает с недопустимым вводом Как перечислить все переменные среды в приложении ac / c ++ Измените программу Я не являюсь владельцем Вернуть два указателя из функции в c C: Чтение текстового файла (с линиями переменной длины) по строке с использованием fread () / fgets () вместо fgetc () (блокирование ввода-вывода или ввода-вывода символов) чтение строк с использованием fscanf Расположение указателей и глобальных переменных в C C неявный extern для глобальной переменной, когда это происходит, как это работает Множественные процессы чтения / записи дочерних процессов на одном и том же канале Каково поведение при преобразовании отрицательного значения с плавающей запятой в unsigned int?

Неудовлетворенная ошибка ссылки: нет файла библиотеки в 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 в 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 .

Вы можете видеть пути, которые использует JVM, если вы запускаете его под strace -fF .

Предложите разместить свой System.loadLibrary () в статическом блоке в classе SimpleJNITest. Возможно, вам понадобится более явное создание объекта 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(); } }