Halil
Halil

Reputation: 2307

Unable make a JNI call to Java getter from C code

I can successfully make JNI calls to java. I fetch an array from JNI call. But I cannot access elements inside this array.

Following is my C code:

void jniInvokeMethod(JNIEnv* env, jclass cls, jobject object) {
    jstring folderName = (*env)->NewStringUTF(env, "");
    jstring token = (*env)->NewStringUTF(env, "Second string");

    jmethodID getFolderContents = (*env)->GetMethodID(env, cls, "getFolderContents", "(Ljava/lang/String;Ljava/lang/String;)[Lcom/labsite/rest/model/FolderOrFile;");
    if (getFolderContents != 0) {
        printf("getFolderContents found\n");
    }

    jobjectArray folderContents = (*env)->CallObjectMethod(env, object, getFolderContents, folderName, token);
    printf("%s\n", folderContents);

    jobject* elem = (*env)->GetObjectArrayElement(env, folderContents, 0);
    for (int i = 0; i < (*env)->GetArrayLength(env, folderContents); i++) {
        jobject folderContentObj = elem[i];
        //jclass cls = (*env)->GetObjectClass(env, folderContentObj);
        jclass folderOrFileCls = (*env)->FindClass(env, "Lcom/labsite/rest/model/FolderOrFile;");
        jmethodID getSizeMethod = (*env)->GetMethodID(env, folderOrFileCls, "getSize", "()J");
        (*env)->CallObjectMethod(env, folderContentObj, getSizeMethod);
    }
}

Following is the method I call from C:

public class Client {
  public FolderOrFile[] getFolderContents(String folderName, String token) {
  ...
  }
}

Visual Studio Debugger stop when (*env)->CallObjectMethod(env, folderContentObj, getSizeMethod) line is being executed, following error message is provided:

Exception thrown at 0x0000000058A498ED (jvm.dll) in mirror.exe: 0xC0000005: Access violation reading location 0x0000000000000009.

Following is the class being returned:

public class FolderOrFile implements Serializable {
  ...
  private long size;

  public long getSize() { return size;}
  ....
}

I am able to invoke getFolderContents() methods. But I cannot invoke a getter of an object. What is wrong with getSize() invocation? (The same thing applies to other methods of FolderOrFile class.

How should I interpret the error message provided by Visual Studio?

Upvotes: 0

Views: 585

Answers (1)

Jorn Vernee
Jorn Vernee

Reputation: 33875

You made a mistake here:

jobject* elem = (*env)->GetObjectArrayElement(env, folderContents, 0);

GetObjectArrayElement returns a jobject, not a jobject*. Since jobject is a typedef for a different pointer type the code still compiles though (with a warning, so be sure to turn those on if you haven't!). Then later on, when you try to index this pointer:

jobject folderContentObj = elem[i];

You actually get a more or less random value for the jobject (whatever happens to be in memory there), so when you try to use that with CallObjectMethod, you get an access violation.

There is no equivalent to Get<PrimitiveType>ArrayElements for object arrays (my guess is that this is due do differences in memory layout in the VM internally). So the way to access the elements, is to call GetObjectArrayElement on every iteration:

jobject folderContentObj = (*env)->GetObjectArrayElement(env, folderContents, i);

Upvotes: 3

Related Questions