Dan Dan - 10 months ago 160
Java Question

Returning null from native methods using JNI

I have some native code which returns a jbyteArray (so byte[] on the Java side) and I want to return null. However, I run into problems if I simply return 0 in place of the jbyteArray.

Some more information:
The main logic is in Java, the native method is used to encode some data into a byte stream. don;t ask.. it has to be done like this. Recently, the native code had to be changed a bit and now it runs horribly horrible slow. After some experimentation, which included commenting out all code in the native method before the return, it turns out that returning 0 causes the slowdown. When returning an actual jbyteArray, everything is fine.

Method signatures for my code:

On the C++ side:

extern "C" JNIEXPORT jbyteArray JNICALL Java_com_xxx_recode (JNIEnv* env, jclass java_this, jbyteArray origBytes, jobject message)

On the Java side:

private static native byte[] recode(byte[] origBytes, Message message);

The native code looks something like this:

jbyteArray javaArray;
if (error != ERROR) {
// convert to jbyteArray
javaArray = env->NewByteArray((jsize) message.size);
env->SetByteArrayRegion(java_array, 0, message.size, reinterpret_cast<jbyte*>(message.buffer()));
if (env->ExceptionOccurred()) {
error = ERROR;
if (error == ERROR) {
return 0; // Does NOT work - doesn't crash, just slows everything down horrible.
else {
return javaArray; // Works perfectly.

Does anyone know of any reasons that this could happen? Is it valid to return NULL from a native method in place of a jbyteArray, or is there another procedure to return null back to Java. Unfortunately, I had no luck on Google.


EDIT: Added additional information.


I do not like the solution to return NULL. If possible you should return some Empty implementations like

return new ArrayList();
return new byte[0];
return new EmptySomeObjectImpl();

Than you do not have worried about NullPointerExceptions

if (error == ERROR) {
    return env->NewByteArray(0);


Try to return this always if you dont want to implement the EmptyObjects.

if (error == ERROR) {
     return javaSrray; // Please test it and than return javaSrray always without if else
else {
    return javaSrray; // Works perfectly.