MAC OS JNI java.lang.UnsatisfiedLinkError Собственный метод

Подпрограммы JNI отлично работают на Wintel, однако при компиляции в ОС MAC вызов C++ "Native Method" приводит к собственному методу java.lang.UnsatisfiedLinkError.

Библиотеки загружаются, таблицы символов кажутся правильными, введено изменение имени rpath.....

Сократился до простого HelloWorld, но все равно не повезло.

--- Система ----

macossys:~ rvc $ uname -a
Darwin macossys 12.4.0 Darwin Kernel Version 12.4.0: Wed May  1 17:57:12 PDT 2013; root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64

---- Трассировки стека:----

macossys:build rvc$ java -Djava.library.path=./bin -classpath ./bin/Bifrost.jar com.nvidia.bifrost.NVbClientTest
Jun 18, 2013 8:50:40 PM com.nvidia.bifrost.NVbClientTest main
WARNING: RVC NVbClient System.getProperty("java.io.tmpdir"):/var/folders/kn/gff3dgh96yv8hmpz1j_ytmk0_nxsrd/T/
Jun 18, 2013 8:50:40 PM com.nvidia.bifrost.NVbClientTest main
WARNING: RVC NVbClient System.getProperty("java.library.path"):./bin
Jun 18, 2013 8:50:40 PM com.nvidia.bifrost.NVbClientTest main
WARNING: RVC NVbClient System.getenv("PATH"):/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
Jun 18, 2013 8:50:40 PM com.nvidia.bifrost.NVbClientTest main
INFO:      RVC NVbClient System.loadedLibrary:
/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/lib/libzip.dylib
/Users/rvc/perForceWorkSpace/p4/sw/gcomp/dev/src/BifrostClientSDK/build/bin/libBifrost.dylib
/Users/rvc/perForceWorkSpace/p4/sw/gcomp/dev/src/BifrostClientSDK/build/bin/libBifrostJNI.dylib

Jun 18, 2013 8:50:40 PM com.nvidia.bifrost.NVbClientTest main
INFO: RVC NVbClient before tester.play()
Jun 18, 2013 8:50:40 PM com.nvidia.bifrost.NVbClientTest play
INFO: RVC play serverName:10.31.193.163 Port:443
NVbClient helloWorldPrintFromJni before helloWorldPrint
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.nvidia.bifrost.NVbClient.helloWorldPrint()I
at com.nvidia.bifrost.NVbClient.helloWorldPrint(Native Method)          “This basically says a problem with JVM finding Native Method Signature”
at com.nvidia.bifrost.NVbClient.helloWorldPrintFromJni(NVbClient.java:141)
at com.nvidia.bifrost.NVbClientTest.play(NVbClientTest.java:88)
at com.nvidia.bifrost.NVbClientTest.main(NVbClientTest.java:61)

----- ссылки rpath кажутся правильными:-----

macossys:build rvc$ otool -L -arch all bin/libBifrostJNI.dylib
bin/libBifrostJNI.dylib:
@rpath/libBifrostJNI.dylib (compatibility version 0.0.0, current version 0.0.0)
@rpath/libBifrost.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 47.1.0)
/usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 47.1.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 744.19.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
macossys:build rvc$ otool -L -arch all bin/libBifrost.dylib
bin/libBifrost.dylib:
@rpath/libBifrost.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 47.1.0)
/usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 47.1.0)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 744.19.0)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
macossys:build rvc$

---- символы существуют:-----

macossys:build rvc$ nm -g sdk/jsrc/jni/CMakeFiles/BifrostJNI.dir/NVbClientJNI.cpp.o | grep -i hello
0000000000001160 T _Java_com_nvidia_bifrost_NVbClient_helloWorldPrint
0000000000001af0 S _Java_com_nvidia_bifrost_NVbClient_helloWorldPrint.eh

---- 32-битная или 64-битная:----

macossys:bin rvc$ file libBifrostJNI.dylib
libBifrostJNI.dylib: Mach-O 64-bit dynamically linked shared library x86_64
macossys:bin rvc$ file libBifrost.dylib
libBifrost.dylib: Mach-O 64-bit dynamically linked shared library x86_64

----- основные ссылки на код---- ^^^^ Вызов Java:

// Used ot verify JNI stack.
int nvbResultR = m_client.helloWorldPrintFromJni();     
m_logger.info("RVC after m_client.helloWorldPrint():"+nvbResultR);

^^^ Вызов/определение метода Java JNI:

public int helloWorldPrintFromJni()
{
System.out.println("NVbClient helloWorldPrintFromJni before helloWorldPrint");
int rtVal = helloWorldPrint();
System.out.println("NVbClient helloWorldPrintFromJni after helloWorldPrint");     
return rtVal;
}

/** Get the current session ID. */
private native int helloWorldPrint();

^^^ c++ Заголовок JNI и сигнатуры методов:

extern "C" JNIEXPORT jint JNICALL Java_com_nvidia_bifrost_NVbClient_helloWorldPrint (JNIEnv *, jobject);

extern "C"
JNIEXPORT jint JNICALL Java_com_nvidia_bifrost_NVbClient_helloWorldPrint(JNIEnv *env, jobject thiz) 
{ 
printf("Made it Java_com_nvidia_bifrost_NVbClient_HelloWorld_print\n"); 
jint result = 1;
return result;
}

----- изменение rpath через cmake:

ADD_CUSTOM_COMMAND(TARGET Bifrost POST_BUILD    
COMMAND ${NAME_TOOL} -id @rpath/libBifrost.dylib ${BIN_DIR}/libBifrost.dylib        
COMMAND ${NAME_TOOL} -change ${BIN_DIR}/libBifrost.dylib @rpath/libBifrost.dylib ${BIN_DIR}/libBifrost.dylib               
)

person user2506103    schedule 20.06.2013    source источник
comment
Решено, проблема заключалась в том, что мы непреднамеренно скрывали символы JNI. Удаление этих директив cMake и теперь ссылки на символы общедоступны. -fvisibility=default -fvisibility-inlines-hidden Большая буква T и маленькая буква t имеют большое значение ;) #› nm -g bin/libBifrostJNI.dylib | grep -i hello 0000000000004e20 T _Java_com_nvidia_bifrost_NVbClient_helloWorldPrint Должна быть заглавная буква T, чтобы быть общедоступной, строчная буква t означает частную/скрытую.   -  person user2506103    schedule 15.07.2013
comment
Позвольте мне попытаться немного почистить это, отформатировав боль....‹br/› Решено, проблема заключалась в том, что мы непреднамеренно скрывали символы JNI. br/›‹br/› Удаление этих директив cmake и теперь ссылки на символы public.‹br/›‹br/› -fvisibility=default -fvisibility-inlines-hidden‹br/› Большая T и маленькая t имеют большое значение ;)‹br/›‹br/› #› nm -g bin/libBifrostJNI .dylib | grep -i hello‹br/› 0000000000004e20 T _Java_com_nvidia_bifrost_NVbClient_helloWorldPrint‹br/›‹br/› Должна быть заглавная буква T, чтобы быть общедоступной, строчная буква t означает частную/скрытую.   -  person user2506103    schedule 15.07.2013
comment
У меня очень похожая проблема, и все мои результаты выглядят так же, как у вас выше. Тем не менее, мой nm -g libtest.dylib | grep getPointer показывает заглавную букву T и правильную _Java_com_test_getPointer, но я все равно получаю UnsatisfiedLinkErrror. Любые идеи, что еще может быть причиной этого? Я опубликовал его здесь, но никто не отвечает.   -  person EntangledLoops    schedule 12.05.2015
comment
Затем посмотрел бы на фактическое несоответствие имени символа/ссылки.   -  person user2506103    schedule 13.05.2015