The rules here are clear. Method ID and field ID values are forever. You can hang onto them. The lookups take some time.
jclass, on the other hand, is generally a local reference. A local reference survives, at most, the duration of a single call to a JNI function.
If you need to optimize, you have to ask the JVM to make a global reference for you. It’s not uncommon to acquire and keep references to common classes like java.lang.String.
Holding such a reference to a class will prevent it (the class) from being garbage-collected, of course.
jclass local = env->FindClass(CLS_JAVA_LANG_STRING);
_CHECK_JAVA_EXCEPTION(env);
java_lang_string_class = (jclass)env->NewGlobalRef(local);
_CHECK_JAVA_EXCEPTION(env);
env->DeleteLocalRef(local);
_CHECK_JAVA_EXCEPTION(env);
The check macro calls:
static inline void
check_java_exception(JNIEnv *env, int line)
{
UNUSED(line);
if(env->ExceptionOccurred()) {
#ifdef DEBUG
fprintf(stderr, "Java exception at rlpjni.cpp line %d\n", line);
env->ExceptionDescribe();
abort();
#endif
throw bt_rlpjni_java_is_upset();
}
}