[Solved] JNI DETECTED ERROR IN APPLICATION: GetStringUTFChars received NULL jstring

JNI DETECTED ERROR IN APPLICATION: GetStringUTFChars received NULL jstring

A/k.myapplicatio: java_vm_ext.cc:545] JNI DETECTED ERROR IN APPLICATION: GetStringUTFChars received NULL jstring
    java_vm_ext.cc:545]     in call to GetStringUTFChars
    java_vm_ext.cc:545]     from void com.sdk.myapplication.MainActivity.triggerGetStringUTFCharsNPE(java.lang.String, java.lang.String)

The reason for the above message, from a Jni method, refers to the case where the JVM calls the method and the GetStringUTFChars entry jstring is empty, it must not refer specifically to the method body where the GetStringUTFChars call has a NULl pointer, but includes other C/C++ method calls in the method that have a NULL pointer. NULL pointer. So we have to look at the crash stack carefully to quickly locate the place where the NULL pointer is generated to avoid invalid output.


the above example is extracted according to our own business code
the example code is as follows
java

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
        triggerGetStringUTFCharsNPE("hello", null);//introduce a null
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();


    public native void triggerGetStringUTFCharsNPE(String p1, String p2);
}

jni

#include <jni.h>
#include <string>
#include <android/log.h>

static const char* TAG = "Demo";


void nestFunction(JNIEnv *env, jstring p2) {
    //Here p1 is simply passed in via a parameter, but the actual business logic may be obtained by other methods/ways
    const char* pStr = env->GetStringUTFChars(p2, nullptr);
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "pStr:%s", pStr);
    env->ReleaseStringUTFChars(p2, pStr);
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_sdk_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}extern "C"
JNIEXPORT void JNICALL
Java_com_sdk_myapplication_MainActivity_triggerGetStringUTFCharsNPE(JNIEnv *env, jobject thiz,
                                                                    jstring p1, jstring p2) {
    const char* pStr1 = env->GetStringUTFChars(p1, nullptr);
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "pStr1:%s", pStr1);
    env->ReleaseStringUTFChars(p1, pStr1);
    //故意让nestFunction产生 JNI DETECTED ERROR IN APPLICATION: GetStringUTFChars received NULL jstring
    nestFunction(env, p2);
}

Read More: