2 Replies Latest reply: Jul 25, 2007 3:11 PM by 843810 RSS

    JNI Function Interception Documentation Correct??

    843810
      I'm looking at the doc located here:

      http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#jniIntercept

      The code sample is also a part of the Java 5 JVMTI doc. Is this code correct? It won't compile the way it is, even when the obvious ommissions are coded back in.
      //JNIEnv originalJniFunctions;
      //JNIEnv redirectedJniFunctions;
      
      jniNativeInterface* originalJniFunctions;
      jniNativeInterface* redirectedJniFunctions;
      int globalRefCount = 0;
      
      jobject JNICALL MyNewGlobalRef(JNIEnv *jni_env, jobject lobj) {
           ++globalRefCount;
                           return originalJniFunctions->NewGlobalRef(jni_env, lobj);
      }
      static void JNICALL vm_init(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
      {
          jvmtiError err;
          jint       runtime_version;
         
          /* The exact JVMTI version doesn't have to match, however this
           *  code demonstrates how you can check that the JVMTI version seen 
           *  in the jvmti.h include file matches that being supplied at runtime
           *  by the VM. 
           */
          err = (*jvmti)->GetVersionNumber(jvmti, &runtime_version);
          if (err != JVMTI_ERROR_NONE) {
           fprintf(stderr, "ERROR: GetVersionNumber failed, err=%d\n", err);
           exit(1);
          } else {
              version_check(JVMTI_VERSION, runtime_version);
          }
      
          err = JVMTI_ERROR_NONE;
          err = (*jvmti)->GetJNIFunctionTable(jvmti, &originalJniFunctions);
          if (err != JVMTI_ERROR_NONE) {
               printf("Couldn't get function table\n, error=%d\n", err);
          }
          err = (*jvmti)->GetJNIFunctionTable(jvmti, &redirectedJniFunctions);
          if (err != JVMTI_ERROR_NONE) {
               printf("Couldn't get function table\n, error=%d\n", err);
          }
          redirectedJniFunctions->NewGlobalRef = MyNewGlobalRef;
          err = (*jvmti)->SetJNIFunctionTable(jvmti, redirectedJniFunctions);
          if (err != JVMTI_ERROR_NONE) {
               printf("Couldn't set function table\n, error=%d\n", err);
          }
      }
      Notice I needed to comment out the JNIEnv function table types. They generate compile errors because when trying to install the MyNewGlobalRef funtion the L value is constant. Once modified to be of type jniNativeInterface* the source compiles. The function is interecepted during runtime but inside the MyNewGlobalRef call, the call to the original NewGlobalRef does not work. I have not been able to get the error because of the environment I am running in. I did use printf's to see that the nothing happend beyond the globalRef call.

      I know more info may be required but I'd first like to ask if my code above is even close to being correct. I was quite confused by the example code in the JVMTI api so I know a coding error on my part is highly likely.

      Thanks!