androidjava-native-interfaceandroid-14

Why No implementation found for boolean android.util.Log.isLoggable on android14?


I'm trying to load my apk from JNI when zygote start. Encounter error No implementation found for boolean android.util.Log.isLoggable on android14 but it is works well on android 13.

I found it load libandroid_runtime.log already. The implementation should be located in there.

What's wrong with me?

04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693] Aborting thread:
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693] "main" prio=10 tid=1 Runnable
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   | group="" sCount=0 ucsCount=0 flags=0 obj=0x12c021d8 self=0xb400007d57689380
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   | sysTid=8651 nice=-20 cgrp=default sched=0/0 handle=0x7e4ed56448
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   | state=R schedstat=( 569334530 51221982 319 ) utm=41 stm=15 core=2 HZ=100
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   | stack=0x7ff3c32000-0x7ff3c34000 stackSize=8188KB
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   | held mutexes= "abort lock" "mutator lock"(shared held)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #00 pc 005c0a38  /apex/com.android.art/lib64/libart.so (art::DumpNativeStack+108) (BuildId: 8bf95d828d83d33315a6ec6a35ddc35f)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #01 pc 005aa3f4  /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack const+804) (BuildId: 8bf95d828d83d33315a6ec6a35ddc35f)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #02 pc 0093670c  /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack const+96) (BuildId: 8bf95d828d83d33315a6ec6a35ddc35f)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #03 pc 00921c1c  /apex/com.android.art/lib64/libart.so (art::AbortState::DumpThread const+56) (BuildId: 8bf95d828d83d33315a6ec6a35ddc35f)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #04 pc 0091a9cc  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort+888) (BuildId: 8bf95d828d83d33315a6ec6a35ddc35f)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #05 pc 00019198  /apex/com.android.art/lib64/libbase.so (android::base::SetAborter::$_0::__invoke+80) (BuildId: 0f50f9c699c6af5881c3be1df5f8ebf2)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #06 pc 00018720  /apex/com.android.art/lib64/libbase.so (android::base::LogMessage::~LogMessage+352) (BuildId: 0f50f9c699c6af5881c3be1df5f8ebf2)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #07 pc 002f0ca0  /apex/com.android.art/lib64/libart.so (art::ClassLinker::FindClass+7708) (BuildId: 8bf95d828d83d33315a6ec6a35ddc35f)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #08 pc 0063281c  /apex/com.android.art/lib64/libart.so (art::JNI<true>::FindClass+656) (BuildId: 8bf95d828d83d33315a6ec6a35ddc35f)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #09 pc 000df254  /system/lib64/libandroid_runtime.so (jniRegisterNativeMethods+68) (BuildId: db8e21c9dd3921811f79cfb920d320bc)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #10 pc 000df1bc  /system/lib64/libandroid_runtime.so (android::register_com_android_internal_os_RuntimeInit+68) (BuildId: db8e21c9dd3921811f79cfb920d320bc)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #11 pc 000e3490  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::startReg+64) (BuildId: db8e21c9dd3921811f79cfb920d320bc)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #12 pc 000e31a0  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start+496) (BuildId: db8e21c9dd3921811f79cfb920d320bc)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #13 pc 00002580  /system/bin/app_process64 (main+1224) (BuildId: af111bda59ddc4b8b33df988040c43b6)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   native: #14 pc 00054580  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+104) (BuildId: 3d07239ca249ec10f6b9ffcbac96d553)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   (no managed stack frames)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693] Pending exception java.lang.UnsatisfiedLinkError: No implementation found for boolean android.util.Log.isLoggable(java.lang.String, int) (tried Java_android_util_Log_isLoggable and Java_android_util_Log_isLoggable__Ljava_lang_String_2I) - is the library loaded, e.g. System.loadLibrary?
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   at boolean android.util.Log.isLoggable(java.lang.String, int) (Log.java:-2)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   at void android.app.Instrumentation.<clinit>() (Instrumentation.java:103)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   at java.lang.Class java.lang.Class.classForName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:-2)
04-29 01:35:38.389  8651  8651 F zygote64: runtime.cc:693]   at java.lang.Class java.lang.Class.forName(java.lang.String, boolean, java.lang.ClassLoader) (Class.java:607)

Solution

  • The good thing about Android is that you can go read the source code. This is android::register_com_android_internal_os_RuntimeInit:

    int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
    {
        const JNINativeMethod methods[] = {
                {"nativeFinishInit", "()V",
                 (void*)com_android_internal_os_RuntimeInit_nativeFinishInit},
                {"nativeSetExitWithoutCleanup", "(Z)V",
                 (void*)com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup},
        };
        return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
            methods, NELEM(methods));
    }
    

    This is the first of many functions called in a loop in android::startReg:

    static const RegJNIRec gRegJNI[] = {
            REG_JNI(register_com_android_internal_os_RuntimeInit), // We are here
            ...
            REG_JNI(register_android_util_Log), // This function associates `android.util.Log#isLoggable` with a native function pointer
            ...
    };
    

    For some reason (and that is not something I can reproduce for you), the FindClass call at the start of jniRegisterNativeMethods decided to log something, but the register_android_util_Log has not had a chance to register android.util.Log#isLoggable yet.

    If you want to investigate this further you will need to attach a debugger to your program and find out what the stack frame inside art::ClassLinker::FindClass+7708 decided to log.