JNI: Catch NewStringUTF Inner-Exception

1.3k Views Asked by At

My JNI code receives a char* src from an external source, converts it to String using jstring jStr = env->NewStringUTF(src), and passes the result jStr to the upper - Java layer.

Some input src values cause the following runtime error (within the call to NewStringUTF):

A/art: art/runtime/java_vm_ext.cc:470] JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal start byte 0xf8
A/art: art/runtime/java_vm_ext.cc:470]     string: 'radio abcdefg ���� ����� ��� ����'
A/art: art/runtime/java_vm_ext.cc:470]     input: '0x72 0x61 0x64 0x69 0x6f 0x20 0x62 0x72 0x65 0x73 0x6c 0x65 0x76 0x20 <0xf8> 0xe3 0xe9 0xe5 0x20 0xe1 0xf8 0xf1 0xec 0xe1 0x20 0xf7 0xe5 0xec 0x20 0xe4 0xf0 0xe7 0xec'
A/art: art/runtime/java_vm_ext.cc:470]     in call to NewStringUTF

None of the methods I used could "catch" this NewStringUTF error/exception:

  • Placing if (env->ExceptionCheck() == JNI_TRUE) after the NewStringUTF call.
  • Placing if (env->ExceptionOccurred()) after the NewStringUTF call.
  • bounding the call to NewStringUTF by a try...catch block.

Note: The question is focused on catching the exception (and by that controlling its impact, so it doesn't crash the application), and not necessarily on resolving it (although it could be useful).

I'm using Android Studio v2.3.3 with NDK v15.2 (most recent to date).

Your assistance would be much obliged.

1

There are 1 best solutions below

0
On

Text datetypes are for text.

Is the data being passed via char * text?

There is no text but encoded text.

What is the character encoding of the text?

NewStringUTF: Constructs a new java.lang.String object from an array of characters in modified UTF-8 encoding.

Android text tends to be standard UTF-8. This looks like Windows-1255 (Hebrew) but only the writer can say.

Regardless, the solution is to use Java character encoding functions to convert your encoded text from a byte array to a Java string (UTF-16). It is easier to call such methods in Java rather than via JNI. So, if it fits your dataflow, copy the char * to a jbyteArray and pass that back to Java where it can be easily converted to a text datatype using the relevant encoding.