0

The following java snippet calls a jni function Java_org_suhail_keylogger_HelperClasses_NativeMethods_unregisterHook :

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {                                           
    jMenuItem1.setEnabled(false);
    jMenuItem2.setEnabled(true);
    try {
       System.loadLibrary("Dll_PKeylogger"); // Load the dll written to listen to the tapping of keys
       nativeMethods.initializeJNIVars(); // called upon the object of a class named NativeMethods
    }catch(Exception exc) {
        exc.printStackTrace();
    }
}

NativeMethods (class,whose object is used to call a JNI C method above) :

public class NativeMethods {

  public native void initializeJNIVars();
  public native void unregisterHook();

  public void displayKeyStrokes() { // FUNCTION THAT IS CALLED BACK FROM JNI C CODE
    System.out.println("Java Message : A Key has been pressed");
  }
}

JNI C method, called by the java code :

void Java_org_suhail_keylogger_HelperClasses_NativeMethods_initializeJNIVars
(JNIEnv *env, jobject obj) {
  jclass cls = (*env)->GetObjectClass(env,obj);
  callBackToDeliverKeyStroke = (*env)->GetMethodID(env,cls,"displayKeyStrokes","()V");
  object = (*env)->NewGlobalRef(env,obj);
  if(object == NULL | callBackToDeliverKeyStroke == NULL | cls == NULL) {
     printf("Initialization error...One of the variable is Null\n");
  }
 }

Method in the same module as the above method that calls the java function:

static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
  JNIEnv *Env;
  (*Env)->CallVoidMethod(Env,object,callBackToDeliverKeyStroke); 
  // I have initialized object and callBackToDeliverKeyStroke in the above method
}

As the execution reaches the last point of execution i.e the function just mentioned above JVM crashes. Why is that ? Where have I made a mistake ?

Suhail Gupta
  • 22,386
  • 64
  • 200
  • 328

1 Answers1

5
JNIEnv *Env;
(*Env)->CallVoidMethod(Env,object,callBackToDeliverKeyStroke);

Env is not initialized.

maba
  • 47,113
  • 10
  • 108
  • 118
  • How do I initialize it in the method ? – Suhail Gupta Oct 04 '12 at 14:26
  • Use `AttachCurrentThread()` to obtain a `JNIEnv` pointer. The native thread remains attached to the VM until it calls `DetachCurrentThread()` to detach itself. – Chris Dennett Oct 04 '12 at 14:26
  • Feels like we have been doing this before, I tried to guide you to that last time: http://stackoverflow.com/questions/10895826/what-is-wrong-with-this-call-to-the-java-method/10896756#10896756 – maba Oct 04 '12 at 14:28
  • In the method `JNI_OnLoad` I read the word _caching_ of JavaVM pointer. Can you explain this. – Suhail Gupta Oct 04 '12 at 23:53
  • @SuhailGupta In your case you can get the `JavaVM` pointer by using `(*env*)->GetJavaVM(env, &jvm);` in the `initializeJNIVars` function and then store that pointer globally in a static variable. – maba Oct 05 '12 at 06:33