Java – JNI calls static methods Is class object necessary?
Start calling static Java methods from C using JNI Specifically, after obtaining jclass (using findclass) and jmethodid (using getstaticmethodid), I continue to call the callstatic * methoda routine series It turns out that all these routines take jclass as the first parameter I began to wonder why class objects are needed: because all the information is provided in getstaticmethodid, the JVM does not need to use class objects to do its work Then, I try to call these routines when passing null for the first parameter, and the call succeeds
My question: is it safe to call these methods with null class objects?
The incentive is: if it's really legal, I won't have to cache class objects for subsequent calls to static methods (and remember to call newglobalref...) Caching jmethodids is sufficient
Solution
No, it is absolutely unsafe to call such static functions with null (or invalid) class pointers
Your exercise can be very successful, for example, if your static method does not reference any other static class members However, if a static Java method references any other static member, the JVM will need a valid class pointer
Example:
Take this simple java demo 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 fragment
... // 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"); It will fail Because when mymain () executes, it will try to access the static variable magic_ number. The JVM will then use the class pointer you provided and assume that it is the void pointer returned by the loaded class But because it is null, the system will be a segment error