title: Android JNI GetMethodID() fails
body: <p>I'm trying to build a Cordova plugin to support a C library used within an Ionic Cordova app.  So far the JavaScript&rarr;Java and Java&rarr;C portions of my code work.  I can successfully debug C code from within Android Studio running on the phone.  However, my C library has a callback method that needs to be passed up the stack (C&rarr;Java&rarr;JavaScript) and I'm having issues getting the JNI methods working properly.  Here's my code so far:</p>
  
  <p><strong>AgentMgrService.Java</strong></p>
  
  <pre><code>package com.example;
  
  import ...
  
  public class AgentMgrService {
  
      private static final String TAG = "AgentMgrService";
      private boolean libLoaded = false;
      private static Context mContext;
  
      public CallbackContext jsCallback;
  
      // C-function interface
      public static native void startAgentMgr(String agentMgrConfig);
      public static native void stopAgentMgr();
  
      // load library
      static {
          System.loadLibrary("lib_agentmgr");
      }
      public AgentMgrService(Context context) {
          mContext = context;
      }
  
      public void startMobileAgentMgr(String agentmgrConfig) throws RemoteException {
          startAgentMgr(agentmgrConfig);
  
      public void testMe() {
          Log.d(TAG, "testMe!");
      }
  
      public String toString() {
          Log.d(TAG, "This is a string!");
          return "This is a string!";
      }
  
  }
  </code></pre>
  
  <p><strong>AgentMgrJni.c</strong></p>
  
  <pre><code>#include ...
  
  static JavaVM* _jamgr_appVm = NULL;
  static jobject _jamgr_appObj = NULL;
  
  void
  Java_com_example_AgentMgrService_startAgentMgr(
          JNIEnv* env,
          jobject thiz,
          jstring config_data)
  {
      if (_jamgr_appObj == NULL) {
        _jamgr_appObj = (*env)-&gt;NewGlobalRef(env, thiz);
      }
  
      //... Stuff happens here ...
  
      jni_callback();
  
  }
  
  int
  jni_callback()
  {
      JNIEnv* env = NULL;
      jint retval = 0;
      jmethodID mid = NULL;
      jclass cls = NULL;
  
      retval = (*_jamgr_appVm)-&gt;GetEnv(_jamgr_appVm, (void**) &amp;env, JNI_VERSION_1_6);
  
      cls = (*env)-&gt;GetObjectClass(env, _jamgr_appObj);
  
  
      //Try the toString() method
      mid = (*env)-&gt;GetMethodID(env, cls, "toString", "()Ljava/lang/String;");
      jobject strObj = (*env)-&gt;CallObjectMethod(env, _jamgr_appObj, mid);
      const char* str = (*env)-&gt;GetStringUTFChars(env, strObj, NULL);
      printf("\nCalling class is: %s\n", str);
      //this prints "class com.example.AgentMgrService"
  
      mid = (*env)-&gt;GetMethodID(env, cls, "testMe", "()V");
      //this returns NULL and thus the below call fails
      (*env)-&gt;CallVoidMethod(env, _jamgr_appObj, mid, jstr);
  
      return retval;
  }
  </code></pre>
  
  <p>When running the above code everything behaves fine until the first <code>GetMethodID()</code>.  When calling <code>toString()</code> I get the boilerplate <code>"class com.example.AgentMgrService"</code> as a reply.  But wait, I overloaded <code>toString()</code>!  Additionally, attempting to get the <code>testMe()</code> returns NULL, so it couldn't find that method.  So I'm in the right class and can in fact call some Java methods from within C, but not methods that I have defined?  I haven't tried making anything static yet but I'm unsure if that would help.</p>