Calling static java methods from JNI

Hi

I'm trying to call a java method from a c++ code (using JNI)

This is called as a callback (java calls native code, and then the native code should call a java callback again)

when the callback is declared as non-static, this works fine:

Callback.java:

class Callbacks{

privatenativevoid nativeMethod(int depth);

privatevoid callback(int depth){

if (depth < 5){

System.out.println("In Java, depth = " + depth +", about to enter C");

nativeMethod(depth + 1);

System.out.println("In Java, depth = " + depth +", back from C");

}else

System.out.println("In Java, depth = " + depth +", limit exceeded");

}

publicvoid callme(){

nativeMethod(0);

}

}

callback.cpp:

JNIEXPORTvoid JNICALL

Java_Callbacks_nativeMethod(JNIEnv *env, jobject obj, jint depth)

{

jclass cls = env->GetObjectClass(obj);

jmethodID mid = env->GetMethodID(cls,"callback","(I)V");

if (mid == 0)

return;

printf("In C, depth = %d, about to enter Java\n", depth);

env->CallVoidMethod(obj, mid, depth);

printf("In C, depth = %d, back from Java\n", depth);

}

but when it is static, it does not work

(I get NoSuchMethodError exception):

java:

class Callbacks{

privatestaticnativevoid nativeMethod(int depth);

privatestaticvoid callback(int depth){

if (depth < 5){

System.out.println("In Java, depth = " + depth +", about to enter C");

nativeMethod(depth + 1);

System.out.println("In Java, depth = " + depth +", back from C");

}else

System.out.println("In Java, depth = " + depth +", limit exceeded");

}

publicvoid callme(){

nativeMethod(0);

}

}

cpp:

JNIEXPORTvoid JNICALL

Java_Callbacks_nativeMethod(JNIEnv *env, jobject obj, jint depth)

{

jclass cls = env->GetObjectClass(obj);

jmethodID mid = env->GetStaticMethodID(cls,"callback","(I)V");

if (mid == 0)

return;

printf("In C, depth = %d, about to enter Java\n", depth);

env->CallStaticVoidMethod(cls, mid, depth);

printf("In C, depth = %d, back from Java\n", depth);

}

Any idea what I'm doing wrong?

[4437 byte] By [orita] at [2007-11-26 19:34:55]
# 1

orit,

This is just a quess, but you could try it and see if it works.

Your calls to get cls and jmethodID are not in the form that the Sun book uses.

For example:

jclass cls = env->GetObjectClass(obj);

Should be:

jclass cls = (*env)->GetObjectClass(env, obj);

and

jmethodID mid = env->GetMethodID(cls, "callback", "(I)V");

Should be:

jjmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");

The examples I used are the instance ones but the static ones have the same format (different JNI function calls).

Now as to why one works and the other doesn't. My guess is that in the instance case your passing the original obj reference and in the static case your passing an invalid cls ref. The methodID should be invalid in both cases, but maybe the JNI code can recover if it has a valid obj ref and can't if both cls and methodID are invalid.

On the other hand you may know more C than I do and your calls may be valid, in which case I'm all wet and you can ignore me. I'll be looking to see how it comes out.

Jim

jjones3566a at 2007-7-9 22:09:02 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2

Thanks for the answer, but this is not the problem

(the difference between my code and your is that mine is in C++ format, where as yours (and the Sun guides) is in C-style.

Anyway, I think I have found the problem - when the Java class is static (with no instance) - the obj pointer is bad,

when I use env->FindClass() instead of env->GetObjectClass(obj) - this works fine.

orita at 2007-7-9 22:09:02 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3

> Hi

>

> I'm trying to call a java method from a c++ code

> (using JNI)

>

> This is called as a callback (java calls native code,

> and then the native code should call a java callback

> again)

>

> when the callback is declared as non-static, this

> works fine:

Your C signatures for the static method and the non-static method are the same.

The signatures are supposed to be different.

That means you didn't run the jnih tool and/or you didn't post the correct signature into your source file.

jschella at 2007-7-9 22:09:03 > top of Java-index,Java HotSpot Virtual Machine,Specifications...