一、 使用JNA调用本地接口
1.1 添加依赖
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.2.2</version>
</dependency>
1.2 继承Library调用本地接口
public interface LicenseFunction extends Library {
LicenseFunction INSTANCE = (LicenseFunction)Native.loadLibrary(Platform.isWindows() ? "your_path/demo.dll" : "your_path/demo.so", LicenseFunction.class);
}
Windows下使用demo.dll,linux下使用demo.so文件(区分64位和32位)。
接着在LicenseFunction 实现c中头文件(.h文件)的方法,例如C文件Bp_log.h文件中代码:
BP_LOG_EXPORT void BP_LogInit(IN const CHAR *pcProcName);
对应Java代码:
void BP_LogInit(String pcProcName);
二、 常见的C类型转java类型(如下表)
java Type | c Type | Native Representation |
byte | char | 8-bit integer |
char | wchar_t | platform-dependent |
short | short | 16-bit integer |
int | int | 32-bit integer |
long | long long | 64-bit integer |
float | float | 64-bit integer |
double | double | 64-bit floating point |
Pointer | array | |
Pointer | void * | |
PointByReference | void ** | |
String | const char * | |
String[ ] | wchar_t* | |
Pointer | unsigned char* | |
NativeLong | long |
三、 常见报错及分析思路
1.1 java.lang.UnsatisfiedLinkError: no sms in java.library.path
从三个方面判断:
(1)检查c的库文件的依赖,使用命令 ldd your_path/demo.so,没有出现not found代表库文件可用,出现not found先执行第二步再次检查一下。
(2)检查环境变量 LD_LIBRARY_PATH
是否已正确设置
使用命令 echo $LD_LIBRARY_PATH,检查是否包含lib库所在目录。若没有,使用export LD_LIBRARY_PATH=/home/demo:$LD_LIBRARY_PATH 添加(/home/demo/demo.so)
(3)检查库文件和系统是否适配
使用命令 file demo.so 查看库文件详细信息。
[root@192 hlf]# file libMyJni.so
libMyJni.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=7b8ebe2641806be26cb72020eb361c794c5cf3f7, not stripped
1.2 A fatal error has been detected by the Java Runtime Environment
授人以鱼不如授人以渔。接下来我简单讲下,查看报错的方法和技巧。
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007ff96455d1ca, pid=1964733, tid=1964734
#
# JRE version: Java(TM) SE Runtime Environment (17.0.7+8) (build 17.0.7+8-LTS-224)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (17.0.7+8-LTS-224, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# C [libTensorEngineCore.so+0x5e1ca] isf::NT::TensorEngine::vDataYUVNV::Create(int, int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)+0x23a
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h" (or dumping to /home/hlf/core.1964733)
#
# An error report file with more information is saved as:
# /home/hlf/hs_err_pid1964733.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
首先,JVM中止会产生堆栈日志,我们可以在hs_err_pid1964733.log中查看报错详细信息。
先关注# Problematic frame:中的内容,会告诉你问题所在。
接着从Stack开始看,
Stack: [0x00007f5ff6caa000,0x00007f5ff74aa000], sp=0x00007f5ff74a6988, free space=8178k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
java中实现c方法签名错误,一般会提示java中哪个类报错,以及对应的方法签名。
下面堆栈日志中,是显示回调函数中结构体转化错误。有两种情况,一种是返回值接收错误,一种是c库文件给你返回null,导致转化错误,JVM崩溃,一般成熟的c库不会出现返回null,大概率是结构体Structure定义出错。
C [libc.so.6+0x177cbd]
j com.sun.jna.Native.getStringBytes(J)[B+0
j com.sun.jna.Native.getString(JLjava/lang/String;)Ljava/lang/String;+1
j com.sun.jna.Pointer.getString(JLjava/lang/String;)Ljava/lang/String;+7
C com.sun.jna.Structure.readField(Lcom/sun/jna/Structure$StructField;)Ljava/lang/Object; (302 bytes) @ 0x00007f608119af34 [0x00007f608119a5c0+0x974]
j com.sun.jna.Structure.read()V+100
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f60969efcbd, pid=3982551, tid=0x00007f5ff74a9640
#
# JRE version: Java(TM) SE Runtime Environment (8.0_111-b14) (build 1.8.0_111-b14)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.111-b14 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libc.so.6+0x177cbd]
#
# Core dump written. Default location: /home/hlf/core or core.3982551
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- T H R E A D ---------------
Current thread (0x00007f5fd8027800): JavaThread "Thread-6" [_thread_in_native, id=3982631, stack(0x00007f5ff6caa000,0x00007f5ff74aa000)]
siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000002
Stack: [0x00007f5ff6caa000,0x00007f5ff74aa000], sp=0x00007f5ff74a6988, free space=8178k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libc.so.6+0x177cbd]
j com.sun.jna.Native.getStringBytes(J)[B+0
j com.sun.jna.Native.getString(JLjava/lang/String;)Ljava/lang/String;+1
j com.sun.jna.Pointer.getString(JLjava/lang/String;)Ljava/lang/String;+7
J 4170 C1 com.sun.jna.Structure.readField(Lcom/sun/jna/Structure$StructField;)Ljava/lang/Object; (302 bytes) @ 0x00007f608119af34 [0x00007f608119a5c0+0x974]
j com.sun.jna.Structure.read()V+100
J 4171 C1 com.sun.jna.Pointer.getValue(JLjava/lang/Class;Ljava/lang/Object;)Ljava/lang/Object; (791 bytes) @ 0x00007f608134acbc [0x00007f608134a720+0x59c]
J 4170 C1 com.sun.jna.Structure.readField(Lcom/sun/jna/Structure$StructField;)Ljava/lang/Object; (302 bytes) @ 0x00007f608119b004 [0x00007f608119a5c0+0xa44]
j com.sun.jna.Structure.read()V+100
j com.sun.jna.Structure.autoRead()V+8
j com.sun.jna.Structure.conditionalAutoRead()V+8
j com.sun.jna.CallbackReference$DefaultCallbackProxy.convertArgument(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;+198
j com.sun.jna.CallbackReference$DefaultCallbackProxy.invokeCallback([Ljava/lang/Object;)Ljava/lang/Object;+95
j com.sun.jna.CallbackReference$DefaultCallbackProxy.callback([Ljava/lang/Object;)Ljava/lang/Object;+2
v ~StubRoutines::call_stub
V [libjvm.so+0x690206] JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0x1056
V [libjvm.so+0x6d20fb] jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*)+0x40b
V [libjvm.so+0x6d84e6] jni_CallObjectMethod+0x196
C [jna2125056312898934246.tmp+0xdfad]
C [jna2125056312898934246.tmp+0xea68]
C [jna2125056312898934246.tmp+0x12398] ffi_closure_unix64_inner+0x88
C [jna2125056312898934246.tmp+0x127c4] ffi_closure_unix64+0x46
C [libTsoon.so+0x493e6] _ZSt13__invoke_implIvRPFvR14tagTsoonResult12retTsoonCodePvPFvS2_PKS0_S3_EEJS1_S2_RS3_RS7_EET_St14__invoke_otherOT0_DpOT1_+0x78
C [libTsoon.so+0x48493] _ZSt8__invokeIRPFvR14tagTsoonResult12retTsoonCodePvPFvS2_PKS0_S3_EEJS1_S2_RS3_RS7_EENSt15__invoke_resultIT_JDpT0_EE4typeEOSE_DpOSF_+0x7f
C [libTsoon.so+0x45be8] _ZNSt5_BindIFPFvR14tagTsoonResult12retTsoonCodePvPFvS2_PKS0_S3_EESt12_PlaceholderILi1EESA_ILi2EES3_S7_EE6__callIvJS1_OS2_EJLm0ELm1ELm2ELm3EEEET_OSt5tupleIJDpT0_EESt12_Index_tupleIJXspT1_EEE+0xce
C [libTsoon.so+0x4527a] _ZNSt5_BindIFPFvR14tagTsoonResult12retTsoonCodePvPFvS2_PKS0_S3_EESt12_PlaceholderILi1EESA_ILi2EES3_S7_EEclIJS1_S2_EvEET0_DpOT_+0x58
C [libTsoon.so+0x44421] _ZSt13__invoke_implIvRSt5_BindIFPFvR14tagTsoonResult12retTsoonCodePvPFvS3_PKS1_S4_EESt12_PlaceholderILi1EESB_ILi2EES4_S8_EEJS2_S3_EET_St14__invoke_otherOT0_DpOT1_+0x4f
C [libTsoon.so+0x43036] _ZSt10__invoke_rIvRSt5_BindIFPFvR14tagTsoonResult12retTsoonCodePvPFvS3_PKS1_S4_EESt12_PlaceholderILi1EESB_ILi2EES4_S8_EEJS2_S3_EENSt9enable_ifIXsrSt6__and_IJSt7is_voidIT_ESt14__is_invocableIT0_JDpT1_EEEE5valueESK_E4typeEOSN_DpOSO_+0x4f
C [libTsoon.so+0x41342] std::_Function_handler<void ()(tagTsoonResult&, retTsoonCode), std::_Bind<void (*()(std::_Placeholder<1>, std::_Placeholder<2>, void*, void (*)(retTsoonCode, tagTsoonResult const*, void*)))(tagTsoonResult&, retTsoonCode, void*, void (*)(retTsoonCode, tagTsoonResult const*, void*))> >::_M_invoke(std::_Any_data const&, tagTsoonResult&, retTsoonCode&&)+0x4f
C [libTsoon.so+0xa1c58] std::function<void ()(tagTsoonResult&, retTsoonCode)>::operator()(tagTsoonResult&, retTsoonCode) const+0x60
C [libTsoon.so+0x9f3dc] Tsoon::Sdk::Interface::ResultConvert(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> const&, tagTsoonResult&, std::function<void ()(tagTsoonResult&, retTsoonCode)>, BreSee::IntelliServerAPI::STATUS)+0x127
C [libTsoon.so+0x8182d] _ZZN5Tsoon3Sdk9Interface17AsynAnalyzerImage9PushImageERKNS1_16stImagePushParamEENKUlN6BreSee16IntelliServerAPI6STATUSERKNS7_14IntelliResultsINS7_10StreamInfoEEEE_clES8_SD_+0x3af
C [libTsoon.so+0x87adc] _ZSt13__invoke_implIvRZN5Tsoon3Sdk9Interface17AsynAnalyzerImage9PushImageERKNS2_16stImagePushParamEEUlN6BreSee16IntelliServerAPI6STATUSERKNS8_14IntelliResultsINS8_10StreamInfoEEEE_JS9_SE_EET_St14__invoke_otherOT0_DpOT1_+0x50
C [libTsoon.so+0x86aa3] _ZSt10__invoke_rIvRZN5Tsoon3Sdk9Interface17AsynAnalyzerImage9PushImageERKNS2_16stImagePushParamEEUlN6BreSee16IntelliServerAPI6STATUSERKNS8_14IntelliResultsINS8_10StreamInfoEEEE_JS9_SE_EENSt9enable_ifIXsrSt6__and_IJSt7is_voidIT_ESt14__is_invocableIT0_JDpT1_EEEE5valueESK_E4typeEOSN_DpOSO_+0x4f
C [libTsoon.so+0x85855] _ZNSt17_Function_handlerIFvN6BreSee16IntelliServerAPI6STATUSERKNS1_14IntelliResultsINS1_10StreamInfoEEEEZN5Tsoon3Sdk9Interface17AsynAnalyzerImage9PushImageERKNSB_16stImagePushParamEEUlS2_S7_E_E9_M_invokeERKSt9_Any_dataOS2_S7_+0x4f
C [libIntelliServerAPI.so+0x1c398] std::function<void ()(BreSee::IntelliServerAPI::STATUS, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> const&)>::operator()(BreSee::IntelliServerAPI::STATUS, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> const&) const+0x60
C [libIntelliServerAPI.so+0x1984e] BreSee::IntelliServerAPI::DefaultAnalyzerAPI<BreSee::IntelliServerAPI::InputParams<BreSee::IntelliServerAPI::StreamInfo>, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> >::resultsCallback(BreSee::IntelliServer::STATUS, BreSee::IntelliServer::IntelliResults const&, std::function<void ()(BreSee::IntelliServerAPI::STATUS, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> const&)> const&)+0x258
C [libIntelliServerAPI.so+0x244fe] _ZSt13__invoke_implIvRMN6BreSee16IntelliServerAPI18DefaultAnalyzerAPIINS1_11InputParamsINS1_10StreamInfoEEENS1_14IntelliResultsIS4_EEEEFvNS0_13IntelliServer6STATUSERKNS9_14IntelliResultsERKSt8functionIFvNS1_6STATUSERKS7_EEERPS8_JSA_SD_RSJ_EET_St21__invoke_memfun_derefOT0_OT1_DpOT2_+0xae
C [libIntelliServerAPI.so+0x236d7] _ZSt8__invokeIRMN6BreSee16IntelliServerAPI18DefaultAnalyzerAPIINS1_11InputParamsINS1_10StreamInfoEEENS1_14IntelliResultsIS4_EEEEFvNS0_13IntelliServer6STATUSERKNS9_14IntelliResultsERKSt8functionIFvNS1_6STATUSERKS7_EEEJRPS8_SA_SD_RSJ_EENSt15__invoke_resultIT_JDpT0_EE4typeEOST_DpOSU_+0x7f
C [libIntelliServerAPI.so+0x22a4a] _ZNSt5_BindIFMN6BreSee16IntelliServerAPI18DefaultAnalyzerAPIINS1_11InputParamsINS1_10StreamInfoEEENS1_14IntelliResultsIS4_EEEEFvNS0_13IntelliServer6STATUSERKNS9_14IntelliResultsERKSt8functionIFvNS1_6STATUSERKS7_EEEPS8_St12_PlaceholderILi1EESP_ILi2EESJ_EE6__callIvJOSA_SD_EJLm0ELm1ELm2ELm3EEEET_OSt5tupleIJDpT0_EESt12_Index_tupleIJXspT1_EEE+0xce
C [libIntelliServerAPI.so+0x21c6a] _ZNSt5_BindIFMN6BreSee16IntelliServerAPI18DefaultAnalyzerAPIINS1_11InputParamsINS1_10StreamInfoEEENS1_14IntelliResultsIS4_EEEEFvNS0_13IntelliServer6STATUSERKNS9_14IntelliResultsERKSt8functionIFvNS1_6STATUSERKS7_EEEPS8_St12_PlaceholderILi1EESP_ILi2EESJ_EEclIJSA_SD_EvEET0_DpOT_+0x58
C [libIntelliServerAPI.so+0x2059b] _ZSt13__invoke_implIvRSt5_BindIFMN6BreSee16IntelliServerAPI18DefaultAnalyzerAPIINS2_11InputParamsINS2_10StreamInfoEEENS2_14IntelliResultsIS5_EEEEFvNS1_13IntelliServer6STATUSERKNSA_14IntelliResultsERKSt8functionIFvNS2_6STATUSERKS8_EEEPS9_St12_PlaceholderILi1EESQ_ILi2EESK_EEJSB_SE_EET_St14__invoke_otherOT0_DpOT1_+0x4f
C [libIntelliServerAPI.so+0x1ef0e] _ZSt10__invoke_rIvRSt5_BindIFMN6BreSee16IntelliServerAPI18DefaultAnalyzerAPIINS2_11InputParamsINS2_10StreamInfoEEENS2_14IntelliResultsIS5_EEEEFvNS1_13IntelliServer6STATUSERKNSA_14IntelliResultsERKSt8functionIFvNS2_6STATUSERKS8_EEEPS9_St12_PlaceholderILi1EESQ_ILi2EESK_EEJSB_SE_EENSt9enable_ifIXsrSt6__and_IJSt7is_voidIT_ESt14__is_invocableIT0_JDpT1_EEEE5valueESZ_E4typeEOS12_DpOS13_+0x4f
C [libIntelliServerAPI.so+0x1dcb2] std::_Function_handler<void ()(BreSee::IntelliServer::STATUS, BreSee::IntelliServer::IntelliResults const&), std::_Bind<void (BreSee::IntelliServerAPI::DefaultAnalyzerAPI<BreSee::IntelliServerAPI::InputParams<BreSee::IntelliServerAPI::StreamInfo>, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> >::*()(BreSee::IntelliServerAPI::DefaultAnalyzerAPI<BreSee::IntelliServerAPI::InputParams<BreSee::IntelliServerAPI::StreamInfo>, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> >*, std::_Placeholder<1>, std::_Placeholder<2>, std::function<void ()(BreSee::IntelliServerAPI::STATUS, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> const&)>))(BreSee::IntelliServer::STATUS, BreSee::IntelliServer::IntelliResults const&, std::function<void ()(BreSee::IntelliServerAPI::STATUS, BreSee::IntelliServerAPI::IntelliResults<BreSee::IntelliServerAPI::StreamInfo> const&)> const&)> >::_M_invoke(std::_Any_data const&, BreSee::IntelliServer::STATUS&&, BreSee::IntelliServer::IntelliResults const&)+0x4f
C [libIntelliServer.so+0x457da] BreSee::IntelliServer::FrameUnitSToI::Callback()+0x8a