Summary
-------
Convert the ClassLoader implementation from its use of finalizer to phantom
reference to handle unloading of a native library when a class loader is unloaded.
Problem
-------
The finalization mechanism is inherently problematic and the JDK implementation
should migrate away from its use of finalizers.
Solution
--------
Use java.lang.ref.Cleaner to register the class loader and the action to unload
a native library.
Specification
-------------
* `JNI_FindClass`
Specify that `JNI_FindClass` uses the system class loader as its context for finding
class when `JNI_FindClass` is called from `JNI_OnUnload` or `JNI_OnUnload_L`.
This is behavioral change because the hotspot implementation has been using
the class loader associated with the native library as the current context. It is
a bug because the spec of `JNI_OnUnload` specifies that it is called in an
unknown context (such as from a finalizer).
<p>
* `JNI_OnUnload` and `JNI_OnUnload_L`
Change the spec as follows to reflect that the native library may be unloaded
after the class loader is GC'ed.
<pre>
-Optional function defined by dynamically linked libraries. The VM calls
-`JNI_OnUnload` when the class loader containing the native library is garbage
-collected.
+Optional function defined by dynamically linked libraries.
+When the class loader containing the native library is garbage collected,
+the VM registers `JNI_OnUnload` to be invoked when the native library
+is being unloaded. It is not specified when the `JNI_OnUnload` function
+is invoked and the native library is unloaded.
</pre>
<pre>
-Optional function defined by statically linked libraries. When the class loader
-containing a statically linked native library 'L' is garbage collected, the VM
-will invoke the `JNI_OnUnload_L` function of the library if such a function is
-exported.
+Optional function defined by statically linked libraries.
+When the class loader containing a statically linked native library 'L'
+is garbage collected, the VM registers `JNI_OnUnload_L` to be invoked
+if such a function is exported. It is not specified when the
+`JNI_OnUnload_L` function is invoked.
</pre>