JDK-4225434 : Java 1.2 class loader fails to load multiple classloaders with native lib
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.2.0,1.2.2,1.3.1
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic,solaris_2.6,windows_nt
  • CPU: generic,x86,sparc
  • Submitted: 1999-03-31
  • Updated: 2001-08-03
  • Resolved: 2001-08-03
Related Reports
Relates :  
Description
Java 1.2 class loader fails to allow repeated loading of the
same share library (from user defined classes with native
method), even though it is loaded via totally distinct 
instances of class loaders.

Error Message:
-------------
At the 2nd execution of the user defined class (with Native
method) via a distinct class loader, we get the following 
error message:

java.lang.UnsatisfiedLinkError: Native Library
/export/home3/yella/fay/tst/show/store/libfay.so 
already loaded in another classloader


Comments
EVALUATION Customer is requesting an extension to a Java API. Bug has been reclassified as an RFE. terrence.miller@Eng 1999-04-07 A native library can not be loaded into two live ClassLoaders objects at the same time and the reasoning for this is obvious -- native code that caches JNI IDs will get wrong answers. The long term fix for this is a way for the native library to tell the VM (on JNI_OnLoad) that it is multiple-ClassLoader safe. That would be an RFE. However when the ClassLoader has died, the ClassLoader.NativeLibrary finalizer could unload the library. Currently we do not do this and this is intentional -- unloading libraries is an MT unsafe operation on NT and there are troubles with runFinalizersOnExit. A workaround would be to have the class that loads a native library be loaded by a shared classloader (through the parenting mechanism of ClassLoaders in 1.2). anand.palaniswamy@Eng 1999-04-08 fred.oliver@East 2001-08-03 Will not fix. There is no API to force the collection of any dead object to occur at any particular time. The ability of the VM to force the unloading of a shared library is not something that can be guaranteed on every platform. Anand's workaround (above) seems practical.
11-06-2004

SUGGESTED FIX Sample Program: -------------- The problem can be reproducted by the attached files: Cl.java - Main driver problem, and a simple MyClassLoader store/Fay.java - a test class with a native method. (note this file must resides under "store". store/fayimp.c - a C problem to implement Fay.java's native method. run -Suggested Fix: ------------- Java 1.2_01 ClassLoader does not unload the native libraries (being kept track at a private class variable "loadedLibraryNames" and private instance variable "nativeLibraries") even upon the loading class loader instance has gone. We suggest to add a finailze method in JDK ClassLoader to clean up the loaded libraries as follows: protected void finalize () throws Throwable { synchronized (nativeLibraries) { int sz=nativeLibraries.size(); for (int i=0; i<sz; i++) { NativeLibrary lib = (NativeLibrary)nativeLibraries.elementAt(i); lib.finalize(); } nativeLibraries.removeAllElements(); } } //finalize Users can then invoke this finalize method (explicitly) to ensure the un-needed libraries are unloaded. a shell script to run the test file (update the LD_LIBRARY_PATH to point to the store directory. all.tar.Z - a compressed tar file of the complete test environment (including above files). To run, simply update the "run" script and execute.
11-06-2004