JNI Calling static methods. Is a class object required?

The use of JNI to invoke static java methods from C ++ will begin. In particular, after receiving jclass (using FindClass) and jmethodID (using GetStaticMethodID), I started calling a series of CallStatic * MethodA routines. It turns out that all of these routines take jclass as the first parameter. I started wondering why the class object was needed: since all the information was provided in GetStaticMethodID, the class object seems unnecessary for the JVM to do the job. Then I tried to call these routines, passing NULL for the first parameter, and the call was successful.

My question is: is it safe to call these methods with an object of class NULL?

Stimulus: if it is really legal, I don’t need to cache the class object for subsequent calls to static methods (do not forget to call NewGlobalRef ....). Caching jmethodID would be enough.

+7
java c ++ static jni
source share
1 answer

No, it is absolutely NOT safe to call such a static function using a null (or invalid) class pointer.

Your practice can be very successful, for example, if your static method does not apply to any other member of the static class. However, if your static java method refers to any other static member, your JVM will need a valid class pointer.

Example:

Take this simple Java MyTest.java :

 public class MyTest { public static void mymain() { System.out.println("Hello, World in java from mymain"); System.out.println(magic_counter); // this will cause a segfault if } // class pointer is null private static int magic_counter=777; } 

And call it with the following JNI C ++ code snippet

 ... // JVM already loaded and initialised jclass cls2 = env->FindClass("MyTest"); if(cls2 == nullptr) { cerr << "ERROR: class not found !"; } else { cout << "Class MyTest found" << endl; jmethodID mid = env->GetStaticMethodID(cls2, "mymain", "()V"); if(mid == nullptr) cerr << "ERROR: method void mymain() not found !" << endl; else { env->CallStaticVoidMethod(cls2, mid); cout << endl; } } 

Call GetStaticMethodID(nullptr, "mymain", "()V"); will fail. Because when mymain() is executed, it will try to access the magic_number static variable. Then the JVM will use the class pointer you provided, and assume that the vaild pointer is returned by the loaded class. But since it is zero, the system will be segfault.

+2
source share

All Articles