title: Why is dlopen() failing when trying to load the Java VM library on 64-bit OS X?
body: <p>I'm trying to load the Java VM library dynamically into a C++ program so I can use the JNI Invocation interface.  Works fine on Linux, but I can't get it to work on Mac.  This test program demonstrates:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;dlfcn.h&gt;
  int main() {
    if (const char *error = dlerror())
      std::cout &lt;&lt; "Flushed existing error: " &lt;&lt; error &lt;&lt; std::endl;
  
    dlopen(
      "/System/Library/Frameworks/JavaVM.framework/Libraries/libjvm.dylib",
      RTLD_NOW); // or RTLD_LAZY, no difference.
  
    if (const char *error = dlerror())
      std::cout &lt;&lt; "ERR: " &lt;&lt; error &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>As written, the program outputs:</p>
  
  <pre><code>ERR: dlopen(/System/Library/Frameworks/JavaVM.framework/Libraries/libjvm.dylib, 2): no suitable image found.  Did find:
      /System/Library/Frameworks/JavaVM.framework/Libraries/libjvm.dylib: mach-o, but wrong architecture
  </code></pre>
  
  <p>I understand that problem -- libjvm.dylib is not a fat-file, it only contains object code for the i386 architecture, and I'm running on a 64-bit Mac, 64-bit OS.  Ref: <a href="http://java.net/jira/browse/MACOSX_PORT-8" rel="nofollow">http://java.net/jira/browse/MACOSX_PORT-8</a></p>
  
  <p>The suggested workaround is to use the server JVM instead.  But changing libjvm.dylib to libserver.dylib causes a different error that I don't understand:</p>
  
  <pre><code>ERR: dlsym(RTLD_DEFAULT, func__entry): symbol not found
  </code></pre>
  
  <p>I get a dlsym error for calling dlopen.  Weird.  nm confirms that the symbol is not present in libserver.dylib:</p>
  
  <pre><code>$ lipo -info libjvm.dylib
  Non-fat file: libjvm.dylib is architecture: i386
  $ nm libjvm.dylib|grep func
  0037b3c0 D _func__entry
           U _jvm__func__entry
  
  $ lipo -info libserver.dylib
  Architectures in the fat file: libserver.dylib are: i386 x86_64 
  $ nm libserver.dylib|grep func
                   U _jvm__func__entry
  </code></pre>
  
  <p>I can't find any documentation on this <code>func__entry</code> and don't know what to try next.</p>
  
  <p><strong>EDIT</strong>
  This testing is on Snow Leopard (10.6.8) with the default JDK/JRE provided by Apple.  I've read that Apple is going to stop providing Java packages, and if you upgrade to Lion, they actually get removed.  It's not clear to me where the new "official" JDK/JRE comes from, but I installed <a href="http://code.google.com/p/openjdk-osx-build/downloads/detail?name=OpenJDK-OSX-1.7-x64-udev-jre-u4-b13-20120308-snowleopard.dmg&amp;can=2&amp;q=" rel="nofollow">this JRE</a> and changed the dlopen call to this library:</p>
  
  <pre><code>"/Library/Java/JavaVirtualMachines/1.7.0u-dev.jre/Contents/Home/lib/server/libjvm.dylib"
  </code></pre>
  
  <p>and now it seems to work.</p>