2015-09-29 5 views
1

Я пишу простую программу Java Hello World для вызова кода из родной библиотеки. Тем не менее, когда я запускаю программу, я получаю следующее сообщение об ошибке:
Неудачная ошибка связи при загрузке библиотеки JNI

Exception in thread "main" java.lang.UnsatisfiedLinkError: no TestJNI in java.library.path 
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1764) 
    at java.lang.Runtime.loadLibrary0(Runtime.java:823) 
    at java.lang.System.loadLibrary(System.java:1044) 
    at TestJNI.<clinit>(TestJNI.java:4) 

Ниже код:
Java:

//filename: TestJNI.java 

public class TestJNI{ 

    static{ 
     System.loadLibrary("TestJNI"); 
    } 

    private native void helloWorld(); 

    public static void main(String[] args){ 
     new TestJNI().helloWorld(); 
    } 
} 

C:

//filname:TestJNI.c 

#include <jni.h> 
#include <stdio.h> 
#include "TestJNI.h" 

JNIEXPORT void JNICALL Java_TestJNI_helloWorld(JNIEnv *env, jobject thisObj){ 
    printf("Hello World!\n"); 
    return; 
} 

: C файл скомпилирован со следующим компилятором, флагами и аргументами:
clang -o TestJNI.jnilib -I/System/Library/Frameworks/JavaVM.framework/Headers -lc -shared TestJNI.c
Затем приложение Java запускается, как показано ниже:
java -Djava.library.path=. TestJNI

Я компиляции и запуска файлов на Mac OS X Yosemite. Кто-нибудь знает, что я делаю неправильно?

ответ

1

Проверьте что java.library.path переменная указывает на каталог, который содержит библиотеку TestJNI. Вы можете попробовать

System.setProperty("java.library.path", "...directory path...");

В качестве альтернативы, используйте System.load("...full path to TestJNI...");, который принимает полный путь к библиотеке (включая расширение файла). (System.loadLibrary указывает на расширение файла, которое я считаю)

+0

Я компилирую файл C в тот же каталог, в котором находится приложение Java. Должен ли я включать полный путь? –

+0

Вам нужно включить полный путь, если вы используете 'System.load' для загрузки библиотеки. Если вы используете 'System.loadLibrary', вы включаете только имя файла библиотеки (без расширения). В последнем случае вы также должны убедиться, что java.library.path указывает на каталог. Я предлагаю первый случай, он более явный. –

+0

Ваше решение работает! Тем не менее, я все равно хотел бы узнать, как загрузить библиотеку, не указав полное имя пути. Что-то не так с передачей '-Djava.library.path = .' в качестве аргумента при запуске приложения? Или у вас есть другие предложения? –

0

В вашей библиотеке должно быть указано что-то .so, чтобы ее можно было загружать как общую библиотеку. Я считаю, что ваша компиляция строка должна выглядеть примерно так:

лязг -shared -undefined dynamic_lookup -o TestJNI.so -I/System/Library/Frameworks/JavaVM.framework/Headers -lc TestJNI.c

+0

Я нахожусь в OS X, поэтому расширение файла библиотеки верное как файл .jnilib. Есть ли у вас другие предложения? –

Смежные вопросы