The important thing to know about using JNI under Tomcat is that one cannot place the native libraries OR their JNI interfaces under the WEB-INF/lib or WEB-INF/classes directories of a web application and expect to be able to reload the webapp without restarting the server. The class that calls System.loadLibrary(String) must be loaded by a classloader that is not affected by reloading the web application itself.
Thus, if you have JNI code that follows the convention of including a static initilaizer like this:
class FooWrapper {
static {
System.loadLibrary("foo");
}
native void doFoo();
}
then both this class and the shared library should be placed in the $CATALINA_HOME/shared/lib directory.
Note that under Windows, you'll also need to make sure that the library is in the java.library.path. Either add %CATALINA_HOME%sharedlib to your Windows PATH environment variable, or place the DLL files in another location that is currently on the java.library.path. There may be a similar requirement for UNIX based system (I haven't checked), in which case you'd also have to add $CATALINA_HOME/shared/lib to the PATH environment variable. (Note: I'm not the original author of this entry.)
The symptom of this problem that I encountered looked something like this -
java.lang.UnsatisfiedLinkError: Native Library WEB-INF/lib/libfoo.so already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1525)
If the UnsatisfiedLinkError is intermittent, it may be related to Tomcat's default session manager. It restored previous sessions at startup. One of those objects may load the JNI library. Try stopping the Tomcat JVM, deleting the SESSIONS.ser file, then starting Tomcat. You may consider changing the session persistence manager at this time.
Note that Tomcat 6.0.14 the $CATALINA_HOME/shared/lib directory does not exist. You will need to add this and you will need to edit $CATALINA_HOME/conf/catalina.properties so that the shared.loader line looks like this shared.loader=$CATALINA_HOME/shared/lib