Native library fails to load when configured in a shared library (V5.0-V5.0.2.2); Native library attempts to load more than once (V5)
 Technote (troubleshooting)
 
Problem(Abstract)
Native libraries (.dll files on Microsoft® Windows® platforms, .so files on UNIX® ) never load when configured in a shared library. This causes a "java.lang.UnsatisfiedLinkException" when application classes call Java™ Native Interface (JNI) methods.

In addition, native libraries might load only once per Java virtual machine (JVM™). When this rule is violated, the server JVM emits a message indicating that "native library <my_native_library> is already loaded in another classloader."
 
Cause
The first problem occurs because the WebSphere® Application Server classloaders do not correctly handle the native library setting in the shared library configuration. This has been repaired in V5.0.2.3, and an interim solution is provided below.
The second problem occurs when an application attempts to reload a library that has already been loaded. This situation can occur inadvertently when utilizing the hot deployment/dynamic reloading features. It can also occur when restarting applications without shutting down the server, when the native library appears in the classpath of the Application Server classloader.

The following solution resolves this problem as well.
 
Resolving the problem
To ensure that a native library lib successfully loads once and only once per application server JVM, place the code that calls System.loadLibrary(lib) into a static block of a class, cls. Create a shared library, specifying the path to lib in the Native Library Path field and the classpath to cls in the Classpath field. Create a Server classloader and associate the shared library to this classloader. Follow the detailed instructions below and note the different steps concerning v5.0.2.2.
  1. Use the administrative console to configure a shared library: For V5.0.2.2 or prior releases, perform step a, for subsequent releases perform step b.
    1. On the administrative console, click on: Environment > Shared Libraries
      1. Click New.
      2. Enter the name of the shared library.
      3. Specify the absolute directory (path) containing the native library DLL or SO in the "Classpath" setting (not the "Native library path" setting).
      4. Append the classpath to the class which invokes System.loadLibrary() in the "Classpath" setting. Make sure to use the correct platform-specific path delimiter (";" for Windows, ":" for UNIX.)

    2. On the administrative console, click on: Environment > Shared Libraries
      1. Click New.
      2. Enter the name of the shared library.
      3. Specify the absolute directory (path) containing the native library DLL or SO in the "Native library path" setting.
      4. Enter the classpath to the class which invokes System.loadLibrary() in the "Classpath" setting.

    3. For either step a. or b., ensure the path specification does not contain the name of the DLL file, just the path to the directory containing the DLL or SO.

    4. Save your changes.

  2. Use the administrative console to define or create a classloader on the application server that will host your applications.
    1. On the administrative console, click: Application Servers > (MyAppServer) > classloader.
    2. Click New. The new classloader appears.
    3. Click OK and save your changes.

  3. Use the administrative console to associate the shared library with the classloader you defined in step 2.
    1. On the administrative console, click: Application Servers > (MyAppServer) > Classloader.
    2. Select the classloader defined in step 2 and click Libraries.
    3. Select the library you defined in step 1 and click Add.
    4. Save your changes.

  4. Stop and Restart the application server and attempt your scenario.

Step 2 introduces a "Server" classloader between the WebSphere Extensions and the WebSphere Application classloaders. This classloader exists for the duration of the Application server (JVM). Because the System.loadLibrary() invocation is in a static block of a class loaded by a "Server" classloader, the native library will load exactly once.

A few concerns regarding shared and native libraries:

All applications can safely use the shared library defined above, because the "Server" classloader exists for the lifetime of the application server. There is no need to define more than one shared library for any native library using the above solution.

A second safety concern: Place the native library in a unique path that will not inadvertently appear in the local classpath of any classloader in the Application Server runtime environment, and ensure this path contains no .jar files or classes unrelated to your shared library content.

If you are curious, the classpath of the Application Server classloaders appears in the output of the classloader dump utility supplied by IBM® WebSphere Level-2 support. If you place the native library in a path that appears in the application or WAR classloaders, it is possible that the native library could get loaded inadvertently by an unexpected classloader.

For instance, if a servlet loads the library and the library appears in the classpath of the application classloader, the application classloader will load the library. When the application is restarted, an exception will occur when the application attempts to load the library again.

Further, if the library path contains .jar files or classes required by applications hosted by the server, these artifacts will be loaded by the "Server" classloader instead of the application classloader (assuming the default PARENT_FIRST classloader mode) which may cause confusing class loading issues.

A native library might load unexpectedly if its path appears in the PATH environment variable of the system. In this case the primordial classloader (Java bootstrap classloader) -- the root of the WebSphere classloader tree -- will find the library, and any dependent native libraries.
 
 
Cross Reference information
Segment Product Component Platform Version Edition
Application Servers Runtimes for Java Technology Java SDK
 
 


Document Information


Product categories: Software > Application Servers > Distributed Application & Web Servers > WebSphere Application Server > Classloader
Operating system(s): Windows
Software version: 5.0.2.3
Software edition:
Reference #: 1180552
IBM Group: Software Group
Modified date: Sep 28, 2004