Paul Fisher writes:
> > which values does the JNI spec say can be cached?
> jfieldID's and jmethodID's. See page 17 of the JNI spec. "Accessing
> Fields and Methods". As long as you keep a live reference to the
> underlying class, the VM ensures that your jfieldIDs and jmethodIDs
> are valid.
That and the JNI tutorial was my starting point, too. I guess
that Christoph has good reasons not to want to support this,
but the fact is: this caching is recommended, official, whatever.
The current discussion aims at class implementation, but I can
assure you that legacy apps in which C code invokes a JVM and
uses native methods to tie Java to the C legacy do exactly the
same thing. And without caching, JNI will simply not be a viable
alternative for an application like a game. How do you propose
to write a Java OpenGL binding (proposal currently prepared
for the ARB) that is darn call-intensive, if a Name Lookup
accompanies every single glWhatever call in the rendering loop?
> Most books that cover JNI probably teach this technique as well.
"Essential JNI" does use it (e.g. p. 146), but, amazingly
enough, does not seem to make a big deal about it.
The book does not even mention multiple VM's, as far
as I got. The SMI tutorials do recommend caching.
> Since IDs are opaque, a VM could check to see if a cached ID is valid
> for a particular VM, if it's not, then the VM could magically fix
> it.
I second that. I tried to do this check in my C++ classes
for "multiple Japhar", and it would be nice to have this
services provided by the VM.
> In order to be fully compatible with existing JNI code, code like the
> following needs to be supported:
>
> static jclass string_clazz;
>
> void init_static_stuff(JNIEnv *env, jclass clazz) {
> string_clazz = (*env)->FindClass(env, "java/lang/String");
> string_clazz = (*env)->NewGlobalRef(env, string_clazz);
> }
>
> See page 14. "Global references remain valid until they are
> explicitly freed."
Exactly what my C++ JClass constructor does (and what my
destructor undoes with a DeleteGlobalRef) - store a jclass,
keep jmethodID and jfieldID alive.
Given the choice between multiple VM and caching, I'd take
caching. If you are in a race, it doesn't matter how many
snails you can get into the competition at once.
b.