I encountered the following problem when calling native code from a Java application deployed on Websphere.
Whenever I was redeploying the WAR file, I started getting UnsatisfiedLinkError - native library already loaded by a classloader.
I knew that the call to "System.loadLibrary" should occur only once in a classloader context. We typically put this code in a static block of a class. But it seemed that in Websphere, when the web application context (classloader) was reloaded, the native libraries were not unloaded. Hence whenever I reloaded the webapp, the above error manifested itself.
To solve the above problem, there were 2 options:
- Put the call to System.loadLibrary inside a static block of a class and load this class as a shared library in Websphere. This will load the class using the System classloader and not the web-application classloader.
- Restart the application server everytime the war/ear file was updated. This solution may or may not be feasible depending on your infrastructure setup.
Imp Caveat: Any crash in the call to the native library crashes the JVM itself. Hence for critical applications, other design alternatives should be thought of. For e.g. writing a separate application that will have a RMI/SOAP/XML interface that will do all the JNI plumbing. This separate application would run in a separate JVM outside of the JEE container JVM. Your webapp would then call this application.