Native libraries are platform-specific library files, including .dll, .so, or *SRVPGM objects, that can be configured within shared libraries. Native libraries are visible to an application class loader whenever the shared library is associated with an application. Similarly, native libraries are visible to an application server class loader whenever the shared library is associated with an application server. When designing a shared library, consider the following conditions regarding Java native library support:
Native libraries are unloaded by the JVM when the class loader that found the library is collected from the heap during garbage collection.
If a shared library that is configured with a native library path is associated with an application, whenever the application is restarted or dynamically reloaded the application might fail with an UnsatisfiedLinkError indicating that the library is already loaded. The error occurs because, when the application restarts, it invokes the shared library class to reload the native library. The native library, however, is still loaded in memory because the application class loader which previously loaded the native library has not yet been garbage collected.
For example, if NativeLib1 is dependent on NativeLib2, then NativeLib2 must be visible to the JVM class loader. The path containing NativeLib2 must be specified on Java library path defined by the LIBPATH environment variable. If a native library configured in a shared library is dependent on other native libraries, the dependent libraries must be configured on the LIBPATH of the JVM hosting the application server in order for that library to load successfully.
Because a native library cannot be loaded more than once by a class loader, it is preferable for native libraries to be loaded within shared libraries associated with the class loader of an application server, because these class loaders persist for the lifetime of the server.
In the class that loads the native library, call System.loadLibrary(native_library) in a static block. For example:
static {System.loadLibrary("native_library");
native_library loads during the static initialization of the class, which occurs exactly once when the class loads.
Associating a shared library with the class loader of an application server, rather than with an application, ensures that the shared library is loaded exactly once by the application server class loader, even though applications on the server are restarted or dynamically reloaded. Because the native library is loaded within a static block, the native library is never loaded more than once.