title: Segfault on JNI_CreateJavaVM
body: <p>I am trying for the first time to load a JVM from C++ via JNI but I can't seem to get it to work. I get a segfault when I call JNI_CreateJavaVM.</p>
  
  <p>The code is pretty straight forward (copied mostly from an online example):</p>
  
  <pre><code>#include&lt;stdio.h&gt;
  #include&lt;jni.h&gt;
  
  using namespace std;
  
  int main(int argc, char** argv) {
  
      printf("Initializing JVM\n");
      JavaVM *jvm;
      JNIEnv *env;
  
      printf("Setting up args\n";
      JavaVMInitArgs vm_args;
      JavaVMOption* options = new JavaVMOption[1];
      options[0].optionString = "-Djava.class.path=.";
      vm_args.version = JNI_VERSION_1_6;
      vm_args.nOptions = 1;
      vm_args.options = options;
      vm_args.ignoreUnrecognized = false;
  
      printf("Attempting to create JVM\n");
      jint rc = JNI_CreateJavaVM(&amp;jvm, (void**)&amp;env, &amp;vm_args);
  
      if(rc != JNI_OK) {
          printf("didn't work :(\n");
      }
      else {
          printf("JVM load succeeded!\n");
          jint ver = env-&gt;GetVersion();
          printf("Version: %i.%i\n", (ver&gt;&gt;16)&amp;0x0f, ver&amp;0x0f);
  
          printf("Cleaning up\n");
          delete options;
          jvm-&gt;DestroyJavaVM();
      }
      printf("Done\n");
  }
  </code></pre>
  
  <p>My LD_LIBRARY_PATH contains /usr/java/jdk1.6.0_45/jre/lib/amd64/server which is the path containing a libjvm.so library. There are a few other libjvm.so libraries on my system, but most of them are for java 1.4. There is only one other jdk 1.6 libjvm.so and I tried using it as well with the same results.</p>
  
  <p>I compile with:</p>
  
  <pre><code>g++ -g -c src/jniExpCppPart.cpp -I/usr/java/jdk1.6.0_45/include -I/usr/java/jdk1.6.0_45/include/linux -o obj/jniExpCppPart.o
  g++ obj/jniExpCppPart.o -L/usr/java/jdk1.6.0_45/jre/lib/amd64/server -ljvm -o exe/jniExp
  </code></pre>
  
  <p>And when I run it within gdb, I get the first three print statements, followed by:</p>
  
  <pre><code>Program received signal SIGSEGV, Segmentation fault
  0x0000003249479e27 in strncmp () from /lib64/libc.so.6
  (gdb) bt
  #0 0x0000003249479e27 in strncmp () from /lib64/libc.so.6
  #1 0x00002aaaaacd8c10 in Arguments::process_sun_java_launcher_properties(JavaVMInitArgs*) () from /usr/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so
  #2 0x00002aaaab2cfe7d in Thread::create_vm(JavaVMInitArgs*, bool*) () from /usr/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so
  #3 0x00002aaaaafcc800 in JNI_CreateJavaVM () from /usr/java/jdk1.6.0_45/jre/lib/amd64/server/libjvm.so
  #4 0x0000000000400761 in main(argc=1, argv=0x7fffffffe568) at src/jni/ExpCppPart.cpp:22
  </code></pre>
  
  <p>My guess is that the issue has more to do with how my environment is set up or how I built the executable rather than the code. Its been a few years since I really dealt with linking shared libraries, so its definitely possible that I messed something up.</p>
  
  <p>Any ideas what I might be doing wrong?</p>
  
  <p><strong>Update</strong>
  I tried loading the library using dlopen instead (because I saw it in some Linux code that uses JNI). It didn't make difference, but I thought I'd include it here to see if it gives anyone a hint of what I may be doing wrong.</p>
  
  <p>Once again I'm copying this by hand from a system that isn't connected to the internet, so there may be some typos.</p>
  
  <pre><code>#include&lt;stdio.h&gt;
  #include&lt;jni.h&gt;
  #include&lt;dlfcn.h&gt;
  
  using namespace std;
  
  //Create type for pointer to the JNI_CreateJavaVM function
  typedef jint (*CreateJvmFuncPtr) (JavaVM**, void**, JavaVMInitArgs*);
  
  //New method returns pointer to the JNI_CreateJavaVM function
  CreateJvmFuncPtr findCreateJvm() {
      CreateJavaFuncPtr createJvm = NULL;
  
      void* jvmLib = dlopen("libjvm.so", RTLD_LAZY); //Get handle to jvm shared library
      char* error = dlerror(); //Check for errors on dlopen
  
      if(jvmLib = NULL || error != NULL) {
          printf("FailedToLoadJVM\n");
      }
  
      //Load pointer to the function within the shared library
      createJvm = (CreateJvmFuncPtr) dlsym(jvmLib, "JNI_CreateJavaVM");
  
      error = dlerror();
      if(error != NULL) {
          printf("Success\n");
      }
  
      return createJVM;
  }
  
  int main(int argc, char** argv) {
  
      printf("Initializing JVM\n");
      JavaVM *jvm;
      JNIEnv *env;
  
      printf("Setting up args\n";
      JavaVMInitArgs vm_args;
      JavaVMOption* options = new JavaVMOption[1];
      options[0].optionString = "-Djava.class.path=.";
      vm_args.version = JNI_VERSION_1_6;
      vm_args.nOptions = 1;
      vm_args.options = options;
      vm_args.ignoreUnrecognized = false;
  
      printf("Attempting to create JVM\n");
      //Old code: jint rc = JNI_CreateJavaVM(&amp;jvm, (void**)&amp;env, &amp;vm_args);
      //New code:
      CreateJvmFuncPtr createJVM = findCreateJvm();
      printf("findCreateJVM() returned 0x%x\n", createJVM);
  
      jint rc = createJVM(&amp;jvm, (void**)&amp;env, &amp;vm_args);
      //End new code
  
      if(rc != JNI_OK) {
          printf("didn't work :(\n");
      }
      else {
          printf("JVM load succeeded!\n");
          jint ver = env-&gt;GetVersion();
          printf("Version: %i.%i\n", (ver&gt;&gt;16)&amp;0x0f, ver&amp;0x0f);
  
          printf("Cleaning up\n");
          delete options;
          jvm-&gt;DestroyJavaVM();
      }
      printf("Done\n");
  }
  </code></pre>
  
  <p>The output (similar to before) shows that everything is successful until it throws a segfault from within the JNI_CreateJavaVM method.</p>
  
  <pre><code>Initializing JVM
  Setting up args
  Attempting to create JVM
  Success!
  findCreateJVM() returned 0xc1e70780
  Segmentation fault
  </code></pre>
  
  <p>So it seems that at the very least the program can find the library/function just fine. But something goes wrong when it's called. To me this indicates that it could either be just a simple API misunderstanding (I'm passing it something other than what I should be) or there's something weird with the shared library. Could this be caused perhaps if the shared library was compiled for an architecture/word size different than my program was compiled for? If so, how can I check the target architecture for both my program and the library?</p>