JNI error: the return type of CallVoidMethodV does not match void ...

0 votes
asked Oct 27, 2019 by gorilla3d (220 points)
Hello, I'm getting an error log message (Android Device Monitor) in my Android app built with Delphi 10.3.2, tested on a Nokia 7 (Android 9) and NVIDIA Shield K1 tablet (Android 7)

java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: the return type of CallVoidMethodV does not match void cn.easyar.FunctorOfVoidFromTargetAndBool.invoke(cn.easyar.Target, boolean)

The error occurs after I execute loadTarget() with a FunctorOfVoidFromTargetAndBool callback.

I'm developing a 3D engine for Delphi and want to provide EasyAR for my customers. I've implemented it by JNI in Delphi language.

The weird thing is, it works fine on a NVidia Shield K1 tablet with Android 7, but not on Nokia 7 with Android 9.

I'm using: EasyAR Sense Basic Version 3.0.1-final-r238a6316e

Is there any special NDK version needed for Android 9?

When I call loadTarget() the app runs into thread switching (20 times) and outputs the following error:

java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: the return type of CallVoidMethodV does not match void cn.easyar.FunctorOfVoidFromTargetAndBool.invoke(cn.easyar.Target, boolean)
java_vm_ext.cc:542]     in call to CallVoidMethodV
java_vm_ext.cc:542]     from boolean cn.easyar.DelayedCallbackScheduler.runOne()
java_vm_ext.cc:542] "Thread-2" prio=10 tid=18 Runnable
java_vm_ext.cc:542]   | group="main" sCount=0 dsCount=0 flags=0 obj=0x12f80338 self=0xd2897000
java_vm_ext.cc:542]   | sysTid=26198 nice=-10 cgrp=default sched=0/0 handle=0xd347f970
java_vm_ext.cc:542]   | state=R schedstat=( 793891478 116117393 806 ) utm=73 stm=6 core=6 HZ=100
java_vm_ext.cc:542]   | stack=0xd3384000-0xd3386000 stackSize=1010KB
java_vm_ext.cc:542]   | held mutexes= "mutator lock"(shared held)
java_vm_ext.cc:542]   native: #00 pc 002d975f  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+134)
java_vm_ext.cc:542]   native: #01 pc 0036ea0b  /system/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+210)
java_vm_ext.cc:542]   native: #02 pc 0036b1c3  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+34)
java_vm_ext.cc:542]   native: #03 pc 00231e37  /system/lib/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+694)
java_vm_ext.cc:542]   native: #04 pc 00232197  /system/lib/libart.so (art::JavaVMExt::JniAbortV(char const*, char const*, std::__va_list)+58)
java_vm_ext.cc:542]   native: #05 pc 000c3f77  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::AbortF(char const*, ...)+42)
java_vm_ext.cc:542]   native: #06 pc 000c6cb3  /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::CheckMethodAndSig(art::ScopedObjectAccess&, _jobject*, _jclass*, _jmethodID*, art::Primitive::Type, art::InvokeType)+506)
java_vm_ext.cc:542]   native: #07 pc 000c5c7b  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, std::__va_list, art::Primitive::Type, art::InvokeType)+534)
java_vm_ext.cc:542]   native: #08 pc 000b767d  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+44)
java_vm_ext.cc:542]   native: #09 pc 000b03d5  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #10 pc 000b3631  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #11 pc 000fcb77  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #12 pc 000fcaa1  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #13 pc 000fc713  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #14 pc 000fbfa1  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #15 pc 000fbe6d  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #16 pc 000fb1db  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #17 pc 000be209  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (???)
java_vm_ext.cc:542]   native: #18 pc 00096089  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyAR.so (Java_cn_easyar_DelayedCallbackScheduler_runOne+204)
java_vm_ext.cc:542]   native: #19 pc 00411a79  /system/lib/libart.so (art_quick_generic_jni_trampoline+40)
java_vm_ext.cc:542]   native: #20 pc 0040d575  /system/lib/libart.so (art_quick_invoke_stub_internal+68)
java_vm_ext.cc:542]   native: #21 pc 003e6bf9  /system/lib/libart.so (art_quick_invoke_stub+224)
java_vm_ext.cc:542]   native: #22 pc 000a1015  /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+136)
java_vm_ext.cc:542]   native: #23 pc 00347b45  /system/lib/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+52)
java_vm_ext.cc:542]   native: #24 pc 0034889d  /system/lib/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue*)+320)
java_vm_ext.cc:542]   native: #25 pc 0026b59b  /system/lib/libart.so (art::JNI::CallBooleanMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*)+450)
java_vm_ext.cc:542]   native: #26 pc 000c73a9  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallMethodA(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, jvalue*, art::Primitive::Type, art::InvokeType)+736)
java_vm_ext.cc:542]   native: #27 pc 000b6e35  /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallBooleanMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*)+44)
java_vm_ext.cc:542]   native: #28 pc 007d6871  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (ExecJNI+344)
java_vm_ext.cc:542]   native: #29 pc 0132f017  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #30 pc 01353323  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #31 pc 012df3e7  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #32 pc 012df3af  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #33 pc 012fa4fb  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #34 pc 012f87cf  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #35 pc 00788c45  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #36 pc 00645c97  /data/app/com.embarcadero.EasyARTest-J_5NMTl6yCVTDvznHGABDg==/lib/arm/libEasyARTest.so (???)
java_vm_ext.cc:542]   native: #37 pc 000636a5  /system/lib/libc.so (__pthread_start(void*)+22)
java_vm_ext.cc:542]   native: #38 pc 0001dff9  /system/lib/libc.so (__start_thread+24)
java_vm_ext.cc:542]   at cn.easyar.DelayedCallbackScheduler.runOne(Native method

1 Answer

0 votes
answered Oct 31, 2019 by gorilla3d (220 points)

I found a solution myself. I've built a separate JavaClass lib which accesses the EasyAR-JAR.

I call loadTarget() inside of Java, to prevent creating an InvocationHandler instance inside of Delphi.

There seems to be a conflict with TJavaLocal (ProxyInterface / InvocationHandler).

Because the EasyAR-suite declares functor interfaces with an "invoke" callback method:

package cn.easyar;

public interface FunctorOfVoidFromTargetAndBool {
  void invoke(Target paramTarget, boolean paramBoolean);
}

The call on FunctorOfVoidFromTargetAndBool.invoke (performed by EasyAR) leads to a method collision, because Delphi-InvocationHandler itself declares also an "invoke" method. JNI picks the wrong "invoke" method which leads to a CheckMethodAndSig exception.

Maybe it is possible to change the method name from "invoke" to something like "onCallback".

Or maybe I'm completely wrong here...

Welcome to EasyAR SDK Q&A, where you can ask questions and receive answers from other members of the community.
...