Android JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception

匿名 (未验证) 提交于 2019-12-03 07:50:05

问题:

I'm trying to run a Googles OCR Tesseract with my android project. I have already complied tesseract with android-ndk and am receiving this error after I try and run the android project.

My environment is as follows

  • Android 5.1.1
  • android-ndk-r10e for windows
  • android-sdk-r22

For reference, I'm building from an example that is listed here Example Link

Thanks in advance!

Here is a snippet of my logcat result:

  I/DEBUG   (  182): Revision: '0'     I/DEBUG   (  182): ABI: 'arm'     I/DEBUG   (  182): pid: 20291, tid: 20337, name: JavaBridge  >>> com.enterprisem     obility.OCR <<<     I/DEBUG   (  182): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------     I/DEBUG   (  182): Abort message: 'art/runtime/check_jni.cc:65] JNI DETECTED ERR     OR IN APPLICATION: JNI GetMethodID called with pending exception 'java.lang.NoSu     chFieldError' thrown in void com.googlecode.tesseract.android.TessBaseAPI.native     ClassInit():-2'     I/DEBUG   (  182):     r0 00000000  r1 00004f71  r2 00000006  r3 00000000     I/DEBUG   (  182):     r4 a0701db8  r5 00000006  r6 0000000b  r7 0000010c     I/DEBUG   (  182):     r8 00000000  r9 b486f520  sl a1c0ac00  fp 00000001     I/DEBUG   (  182):     ip 00004f71  sp a07006d8  lr b6e503c5  pc b6e72f6c  cpsr     60070010     I/DEBUG   (  182):     I/DEBUG   (  182): backtrace:     I/DEBUG   (  182):     #00 pc 00039f6c  /system/lib/libc.so (tgkill+12)     I/DEBUG   (  182):     #01 pc 000173c1  /system/lib/libc.so (pthread_kill+52)     I/DEBUG   (  182):     #02 pc 00017fd3  /system/lib/libc.so (raise+10)     I/DEBUG   (  182):     #03 pc 00014795  /system/lib/libc.so (__libc_android_abor     t+36)     I/DEBUG   (  182):     #04 pc 00012f44  /system/lib/libc.so (abort+4)     I/DEBUG   (  182):     #05 pc 00228cd7  /system/lib/libart.so (art::Runtime::Abo     rt()+170)     I/DEBUG   (  182):     #06 pc 000a7371  /system/lib/libart.so (art::LogMessage::     ~LogMessage()+1360)     I/DEBUG   (  182):     #07 pc 000b1b17  /system/lib/libart.so (art::JniAbort(cha     r const*, char const*)+1118)     I/DEBUG   (  182):     #08 pc 000b2055  /system/lib/libart.so (art::JniAbortF(ch     ar const*, char const*, ...)+68)     I/DEBUG   (  182):     #09 pc 000b530f  /system/lib/libart.so (art::ScopedCheck:     :ScopedCheck(_JNIEnv*, int, char const*)+1346)     I/DEBUG   (  182):     #10 pc 000b7755  /system/lib/libart.so (art::CheckJNI::Ge     tMethodID(_JNIEnv*, _jclass*, char const*, char const*)+36)     I/DEBUG   (  182):     #11 pc 001332f7  /data/app/com.enterprisemobility.OCR-1/l     ib/arm/libtess.so (Java_com_googlecode_tesseract_android_TessBaseAPI_nativeClass     Init+46)     I/DEBUG   (  182):     #12 pc 0000614d  /data/dalvik-cache/arm/data@app@com.ente     rprisemobility.OCR-1@base.apk@classes.dex     W/ActivityManager(  536):   Force finishing activity 1 com.enterprisemobility.OC     R/.MainActivity     I/DEBUG   (  182):     I/DEBUG   (  182): Tombstone written to: /data/tombstones/tombstone_07 

回答1:

The Abort message is relatively clear: you call GetFieldID(cls, fieldName) for a field name that does not exist in the class you pass to this function, but you don't check for that error, and continue to call other JNI functions. Unfortunately, you cannot ignore such errors. You must call ExceptionClear() before calling GetMethodID() or most of the JNI functions.

You can use addr2line to find which specific call to getMethodID() crashed, and based on this, derive which call to GetFieldID(cls, fieldName) failed. But I would advise to add error checking to all your JNI calls, because tomorrow some other function may throw an exception.



回答2:

I have the same problem,and it confuse me 2 days.Finally the reason is that I pass the wrong object type.For example, the java code is

public OverlayLine(int mWidth,List<GeoPoint> mPoints); 

and I register jni method as below:

gClass.mInitMethod = env->GetMethodID(gObject, "<init>", "(ILjava/lang/Object;)V"); 

and gets the error message as Errol encounter.And I fix the code

gClass.mInitMethod = env->GetMethodID(gObject, "<init>", "(ILjava/util/List;)V"); 

and the error gone.That you should pass the precise object type rather than 'Ljava/lang/Object;'.



回答3:

you should use ndk-stack tool in android NDK to find out the crashed position. see the link about ndk stack.

adb logcat > /tmp/foo.txt  $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump foo.txt 


回答4:

Most likely the JNI mappings were incorrectly defined in your C++ code. JNI has very strict contracts about type mappings with Java. For example, before calling a Java object's method from JNI, we need its signature. So the method:

long myMethod (int n, String s, int[] arr);

is seen from JNI with the signature:

(ILJAVA/LANG/STRING;[I])J

You can read a very comprehensive overview of these rules here: http://www.rgagnon.com/javadetails/java-0286.html



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!