Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Correct JNI_OnLoad JNI_OnUnLoad approach for cacheing jvm ref?

SreramJan 18 2012 — edited Jan 19 2012
Currently am successful in calling a C API from Java. What am basically trying to do here is catch an event in C program, and callback the Java instance, to handle it in my Java code (Similar to a event handling in Swing).

I have implemented the event handling in Windows in C, and will be implementing it soon for Linux and Mac, but how do I cache jvm reference? As far as i searched in other forums, I realize the need for implementing JNI_OnLoad and JNI_OnUnLoad functions in C.

But am a bit confused in the concept of global references.

JavaVM *cached_jvm;

JNIEXPORT jint JNICALL myJavaClassCallback() {
jclass Class_myclass;
jmethodID MID_myclass_mymethod;
#ifdef JNI_VERSION_1_2
res = (*cached_jvm)->AttachCurrentThread(cached_jvm, (void**)&env, NULL);
#else
res = (*cached_jvm)->AttachCurrentThread(cached_jvm, &env, NULL);
#endif
if (res < 0) {
printf("Attach failed\n");
return;
}
Class_myclass = (*env)->FindClass(env, "mypackage.MyClass");
if (Class_myclass == NULL) {
goto detach;
}
MID_myclass_mymethod = (*env)->GetStaticMethodID(env, Class_myclass, "myMethod", "(Z)V");
if (MID_myclass_mymethod == NULL) {
goto detach;
}
jboolean jbool = JNI_FALSE;
(*env)->CallStaticVoidMethod(env, cls, MID_myclass_mymethod, jbool);//Correct?
detach:
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
}
(*jvm)->DetachCurrentThread(jvm);
}


JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM jvm, void reserved) {
JNIEnv *env;
cached_jvm = jvm; /* cache the JavaVM pointer */

if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
return JNI_ERR; /* JNI version not supported */
}
return JNI_VERSION_1_2;
}


JNIEXPORT void JNICALL JNI_OnUnload(JavaVM jvm, void reserved) {
//Should i implement some delete reference here???
}

I have two questions here.

One, should i call some delete reference (or some function like deleteallrefereces (??)[if available]) on JNI_OnUnload?
And two is my passing of jboolean argument correct?

Thanks,
Sreram

Comments

Sreram
And one more thing. Am using Java SE6. so should i put JNI_VERSION_1_6 or JNI_VERSION_1_2 will work?
EJP
But am a bit confused in the concept of global references.
You're not using global references. Your question?
One, should i call some delete reference (or some function like deleteallrefereces (??)[if available]) on JNI_OnUnload?
No.
And two is my passing of jboolean argument correct?
Yes, but you don't actually need the variable, just pass JNI_FALSE directly as the argument.
should I put JNI_VERSION_1_6
Yes, if there is such a thing.
or JNI_VERSION_1_2 will work?
Yes.
Sreram
<quote>
You're not using global references. Your question?
</quote>
Oops! I realize now am not using global references. But i have two questions regarding global and local references.

One, If we create a global reference, and use it in our program, how and when do we delete the reference? When, the answer might be after the reference is no longer in use, but if the reference is used all over the c code, should we delete it manually using DeleteGlobalRef in Unload function? Should DeleteLocalRef be called in every method, where the reference might be used?

And two, why the code

<quote>
static jclass stringClass = NULL;
jmethodID cid;
jcharArray elemArr;
jstring result;
if (stringClass == NULL) {
stringClass = (*env)->FindClass(env,"java/lang/String");
if (stringClass == NULL) {
return NULL; /* exception thrown */
}
}
/* It is wrong to use the cached stringClass here, because it may be invalid. */
cid = (*env)->GetMethodID(env, stringClass, "<init>", "([C)V");
}
</quote>
is wrong? I understand the above code is wrong as the stringClass variable here may become invalid and Garbage collector might have removed the variable from memory, but what i don't understand is how will it become invalid when the variable is still used in the same method?

<quote>No.</quote>

I understand i mustn't delete any references as i haven't used any global references, but my question was regarding the local and global references i stated above.
<quote>Yes, but you don't actually need the variable, just pass JNI_FALSE directly as the argument.</quote>

I knew it. But just wanted to confirm as in my actual code, i will be passing boolean argument based on the condition i determine, at runtime.

<quote>Yes, if there is such a thing. Yes.</quote>

The reason i asked this question is, I am using 1.6 version, but am giving 1.2 .. Is it like it will compare with version 1.2 and return true if version is 1.2 or higher?
EJP
One, If we create a global reference, and use it in our program, how and when do we delete the reference?
When you've finished with it.
When, the answer might be after the reference is no longer in use, but if the reference is used all over the c code, should we delete it manually using DeleteGlobalRef in Unload function?
Not really, the entire JVM is being unloaded, it's probably already too late.
Should DeleteLocalRef be called in every method, where the reference might be used?
Only if you're trying to limit local references. See the discussion in the JNI Specification. All local references are released when your JNI method exits.
And two, why the code
...
is wrong?
It's a local reference, so it's only valid throughout a single JNI call. To reuse across JNI calls, make a GlobalRef or weak global ref out of it, or reacquire it every time you need it.
how will it become invalid when the variable is still used in the same method?
It won't. It can become invalid between methods.
The reason i asked this question is, I am using 1.6 version, but am giving 1.2 .. Is it like it will compare with version 1.2 and return true if version is 1.2 or higher?
It will return true if it can support that version. It can.
1 - 4
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Feb 16 2012
Added on Jan 18 2012
4 comments
4,786 views