title: JNI loses reference to native methods
body: <p>As an example for later use in Android I wrote a simple callback interface. While doing so i ran into the following error or bug or whatever. In C the two commented lines are supposed to be executed resulting in calling the C callback onChange. But instead i get an UnsatisfiedLinkError. Calling the native Method directly in Java works just fine. Calling it directly from C as presented here in the example also produces the UnsatisfiedLinkError. I'm open for any advice concerning this issue or work arounds and so on.
  The Java Part:</p>
  
  <pre><code>import java.util.LinkedList;
  import java.util.Random;
  
  interface Listener {
      public void onChange(float f);
  }
  class Provider {
      LinkedList&lt;Listener&gt; all;
      public Provider() {
          all = new LinkedList&lt;Listener&gt;();
      }
      public void registerChange(Listener lst) {
          all.add(lst);
      }
      public void sendMsg() {
          Random rnd = new Random();
          for(Listener l : all) {
              try {
                  l.onChange(rnd.nextFloat());
              }
              catch(Exception e) {
                  System.out.println(e);
              }
          }
      }
  }
  class Inheritance implements Listener {
      static public void main(String[] args) {
          System.load(System.getProperty("user.dir") + "/libinheritance.so");
      }
      public native void onChange(float f);
  }
  </code></pre>
  
  <p>The C Part:</p>
  
  <pre><code>#include "inheritance.h"
  
  jint JNI_OnLoad(JavaVM *jvm, void *reserved) {
      JNIEnv *env;
      (*jvm)-&gt;GetEnv(jvm, (void**)&amp;env, JNI_VERSION_1_4); 
  
      jclass inheritance = (*env)-&gt;FindClass(env, "Inheritance");
      jobject o_inheritance = (*env)-&gt;NewObject(env, inheritance, (*env)-&gt;GetMethodID(env, inheritance, "&lt;init&gt;", "()V"));
      jclass provider = (*env)-&gt;FindClass(env, "Provider");
      jobject o_provider = (*env)-&gt;NewObject(env, provider, (*env)-&gt;GetMethodID(env, provider, "&lt;init&gt;", "()V"));
  
      g_inheritance = (*env)-&gt;NewGlobalRef(env, inheritance);
      g_provider = (*env)-&gt;NewGlobalRef(env, provider);
  
      (*env)-&gt;CallVoidMethod(env, o_inheritance, (*env)-&gt;GetMethodID(env, inheritance, "onChange", "(F)V"), 1.0);
  
      //(*env)-&gt;CallVoidMethod(env, o_provider, (*env)-&gt;GetMethodID(env, provider, "registerChange", "(LListener;)V"), o_inheritance);
      //(*env)-&gt;CallVoidMethod(env, o_provider, (*env)-&gt;GetMethodID(env, provider, "sendMsg", "()V"));
  
      (*env)-&gt;DeleteLocalRef(env, o_inheritance);
      (*env)-&gt;DeleteLocalRef(env, o_provider);
  
      return JNI_VERSION_1_4;
  }
  JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved) {
      JNIEnv *env;
      (*jvm)-&gt;GetEnv(jvm, (void**)&amp;env, JNI_VERSION_1_4); 
      (*env)-&gt;DeleteGlobalRef(env, g_inheritance);
      (*env)-&gt;DeleteGlobalRef(env, g_provider);
   }
  JNIEXPORT void JNICALL Java_Inheritance_onChange(JNIEnv *env, jobject self, jfloat f) {
      printf("[C] %f\n", f);
  }
  </code></pre>
  
  <p>The header file:</p>
  
  <pre><code>#include &lt;jni.h&gt;
  /* Header for class Inheritance */
  
  #ifndef _Included_Inheritance
  #define _Included_Inheritance
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  jclass g_inheritance, g_provider;
  
  /*
   * Class:     Inheritance
   * Method:    onChange
   * Signature: (F)V
   */
  JNIEXPORT void JNICALL Java_Inheritance_onChange(JNIEnv *, jobject, jfloat);
  
  jint JNI_OnLoad(JavaVM *, void *);
  
  #ifdef __cplusplus
  }
  #endif
  #endif
  </code></pre>
  
  <p>Compilation:</p>
  
  <pre><code>gcc -c -fPIC -I /usr/lib/jvm/java-6-openjdk/include -I /usr/lib/jvm/java-6-openjdk/include/linux/inheritance.c inheritance.h
  gcc -g -o -shared libinheritance.so -shared -Wl,-soname,libinheritance.so -lc inheritance.o
  </code></pre>