Tomcat的Release Notes 里有這么一段話:
=======================
JNI Based Applications:
=======================
Applications that require native libraries must ensure that the libraries have
been loaded prior to use.? Typically, this is done with a call like:
? static {
??? System.loadLibrary("path-to-library-file");
? }
in some class.? However, the application must also ensure that the library is
not loaded more than once.? If the above code were placed in a class inside
the web application (i.e. under /WEB-INF/classes or /WEB-INF/lib), and the
application were reloaded, the loadLibrary() call would be attempted a second
time.
To avoid this problem, place classes that load native libraries outside of the
web application, and ensure that the loadLibrary() call is executed only once
during the lifetime of a particular JVM.
簡單地說就是JNI庫的加載在啟動Tomcat的JVM中只能進行一次,如果兩次執行System.loadLibrary("path-to-library-file");將會導致錯誤(Error,不是Exception):
java.lang.UnsatisfiedLinkError: Native Library xxx.dll already loaded in another classloader。
可是這段話并沒有給出具體的解決辦法。我要使用的一個NT登錄驗證的JAAS模塊碰到了這個問題:我把包含這個語句的庫放在了某個web應用程序的lib目錄下,結果當修改了某個web配置文件導致這個程序的context reload時,JAAS模塊就不能使用,因為它又重新加載JNI庫導致錯誤。只有重新啟動整個tomcat才能恢復正常,十分麻煩。
找了好久,終于在一個大俠的文章(http://cuiyingfeng.blog.ccidnet.com/blog/ccid/do_showone/tid_48232.html)中找到了解決方法:
1、加載JNI庫的包放在Tomcat的common/lib目錄下,而不要放在各context的lib目錄下;
2、每次加載JNI庫之前檢查是否已經加載過。
由于加載語句不是我能控制的,所以第二種方法不能實現,于是我就通過第一種方法把這個問題解決了。