HELP IN JNI (1.4) : how to get informations from a jclass pointer ?

Hi,

I am integrating a JVM inside an already built product in C and Objective C. I need to build hash tables of jclass pointers. The problem is :

On two different JNI interactions, when for instance you ask for the jclass pointer of "java/lang/String", you get different pointers. So I cannot built a hash key based on the jclass value. Only

(*env)->IsSameObject(env,jclass1,jclass2) can help to recognize that those pointers points to the same java class.

So it would be usefull for me to grab (efficiently) a stable information, such as the name of the class, to build a hash key from.

Anybody could tell me how can I do this ?

Thanks in advance,

Regards,

C.Dore

[731 byte] By [cdore] at [2007-9-26 10:30:23]
# 1
env->CallStaticObjectMethod(env, cls, mID); whereenv is your JNIEnv*cls is your jclass argumentmID is the method ID env returned to you for getName, ()Ljava/lang/String; calling GetMethodID
thpreusser at 2007-7-1 22:49:24 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2

This does not seem to work...

Here is what I tried :

jmethodID testMeth;

jclass testClass=(*env)->GetMethodID(env,(*env)->FindClass(env,"com/mycom/MyVcass"),

testMeth=(*env)->GetMethodID(env,(*env)->FindClass(env,"java/lang/Class"),"getName","()Ljava/lang/String;");

cname= (*env)->CallStaticObjectMethodA(env,testClass,testMeth,NULL);

the latest statement crashes....

Anybody can help ?

cdore at 2007-7-1 22:49:24 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3

Yes, sorry, realized that myself and actually thought I would have posted the correct solution but I guess I forgot about it. Here it is:

[code]

import java.util.Hashtable;

public final class Test {

static { System.loadLibrary("test"); }

private static native Hashtable makeHash();

public static void main(String[] args) {

Hashtable h = makeHash();

h.put("ba", "ba");

System.out.println(h);

} // main(String[])

}

// NATIVE portion:

#include <jni.h>

/* Header for class Test */

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class:Test

* Method:makeHash

* Signature: ()Ljava/util/Hashtable;

*/

JNIEXPORT jobject JNICALL Java_Test_makeHash(JNIEnv *env, jclass klass) {

jclasshashClass = (*env)->FindClass(env, "java/util/Hashtable");

jmethodID hashConstr = (*env)->GetMethodID(env, hashClass, "<init>", "()V");

jobjecthash= (*env)->NewObject(env, hashClass, hashConstr);

return hash;

}

#ifdef __cplusplus

}

#endif

thpreusser at 2007-7-1 22:49:24 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 4

Well, now I know why I missed my post, I confused your thread again. But I also have a solution for you:

import java.util.Hashtable;

public final class Test {

static { System.loadLibrary("test"); }

private static native String getClassName(Object o);

public static void main(String[] args) {

System.out.println(getClassName(new String()));

} //* main(String[])

}

Native portion:

#include <jni.h>

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class:Test

* Method:makeHash

* Signature: ()Ljava/util/Hashtable;

*/

JNIEXPORT jobject JNICALL Java_Test_getClassName(JNIEnv *env, jclass klass, jobject o) {

jclassclassClass = (*env)->FindClass(env, "java/lang/Class");

jobjectoClass= (*env)->GetObjectClass(env, o);

jmethodID getName= (*env)->GetMethodID(env, classClass, "getName", "()Ljava/lang/String;");

return (*env)->CallObjectMethod(env, oClass, getName);

}

#ifdef __cplusplus

}

#endif

thpreusser at 2007-7-1 22:49:24 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 5
OK. It works fine.If I understand well, getObjectClass returns a jclass, which is in fact a reference ot the Class object we can grab through the Object::getClass() method.Thanks !C.Dore
cdore at 2007-7-1 22:49:24 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 6

Yes, you are correct. It actually returns a jclass, which is a subtype of jobject. This subtype relationship is modelled cleanly only if you use C++. In C it is simply realized by a typedef, which, in fact, makes both types identical. I chose to declare the variable only a jobject since I only access it as an instance of an object. If you need any functionality of the class itself, you are certainly free to declare it as jclass.

thpreusser at 2007-7-1 22:49:24 > top of Java-index,Java HotSpot Virtual Machine,Specifications...