Linux JNI Tricks

Linux distros have started to include a GNU Java tool chain, but many users still prefer Sun JVMs. This can get messy especially if you are trying to use JNI, because the C/C++ part will be compiled via the GNU tool chain but the JVM trying to load it up will be from Sun. Bombing with unsatisfied links to __gcj_personality_v0 or __gxx_personality_v0 is a common malaise (google to see how bad this is). Here is the fix. After installing Sun's JVM, Be sure to install java-1.5.0-sun-compat-1.5.0.08-1jpp (matching version to your Sun JVM, obviously). Next, run

# alternatives --config java
There are 2 programs which provide 'java'.
  Selection    Command
-----------------------------------------------
   1           /usr/lib/jvm/jre-1.4.2-gcj/bin/java
*+ 2           /usr/lib/jvm/jre-1.5.0-sun/bin/java
Enter to keep the current selection[+], or type selection number: 
Next, check that your linker line in the Makefile looks like this:
g++ -fPIC -shared -o $@ -Wl,--whole-archive,-soname,$@ \
   $(OBJS) -lgcj -Wl,--no-whole-archive
The -lgcj is all-important. Also make sure you have -fPIC set in compile lines. In addition, if you are running your Java job via ant, you can set LD_LIBRARY_PATH from inside build.xml, as shown:
<target name="run" ...>
  <java classname=...>
    <env key="LD_LIBRARY_PATH" value="..."/> <!-- for UNIX -->
    <env key="PATH" value="..."/> <!-- for Win32/Cygwin -->
  </java>
</target>