Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8188069

JNI FindClass needs to specify the class loading context used for library lifecycle hooks

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 10
    • hotspot
    • None
    • behavioral
    • medium
    • Hide
      Existing native library whose `JNI_OnUnload` calls `FindClass` to load a class defined by a custom class loader that is the class loader associated with the native library or its ancestor may fail. Existing unload hooks will continue to work if `FindClass` is called to find the named class that is defined by the system class loader and built-in loaders.

      If an unload hook calls `FindClass` to find a class that is defined by the class loader being unloaded, the existing code should be rewritten not to depend on an unreachable class. The JNI specification specifies that the unload hook is called from an unknown context and should be conservative what it can call. It is believed that it is rare to have such native library being impacted by this change (loaded by custom loader and loading a class when its class loader is being unloaded) and such code is so fragile depending on objects that might be garbage collected when access.

      If an unload hook calls `FindClass` to find a class that is defined by the parent class loader (or ancestor) which is not the built-in class loader and it is still strongly reachable, the existing code has to be modified to cache the jclass and make a JNI reference before the native library is unloaded.

      It is believed that the compatibility risk should be low but marked as medium because it is uncertain how existing applications depend on these behaviors.
      Show
      Existing native library whose `JNI_OnUnload` calls `FindClass` to load a class defined by a custom class loader that is the class loader associated with the native library or its ancestor may fail. Existing unload hooks will continue to work if `FindClass` is called to find the named class that is defined by the system class loader and built-in loaders. If an unload hook calls `FindClass` to find a class that is defined by the class loader being unloaded, the existing code should be rewritten not to depend on an unreachable class. The JNI specification specifies that the unload hook is called from an unknown context and should be conservative what it can call. It is believed that it is rare to have such native library being impacted by this change (loaded by custom loader and loading a class when its class loader is being unloaded) and such code is so fragile depending on objects that might be garbage collected when access. If an unload hook calls `FindClass` to find a class that is defined by the parent class loader (or ancestor) which is not the built-in class loader and it is still strongly reachable, the existing code has to be modified to cache the jclass and make a JNI reference before the native library is unloaded. It is believed that the compatibility risk should be low but marked as medium because it is uncertain how existing applications depend on these behaviors.
    • Other
    • SE

      Summary

      Propose JNI_OnLoad to use the class loader that requests to load this native library and JNI_OnUnload to use the system class loader as the class loading context respectively.

      Problem

      The current JNI spec does not specify the class loading context used for JNI_OnLoad hooks whereas the implementation uses the class loader that requests to load the native library as the class loading context which is very reasonable. On the other hand, the JNI spec specifies that JNI_OnUnload is called in an unknown context whereas the implementation uses the class loader being unloaded as the context.

      Solution

      Use the system class loader as the class loading context for JNI_OnUnload hook, that is consistent with FindClass currently specified when there is no context. No change in the class loading context for JNI_OnLoad hook but clarify it in JNI_OnLoad spec.

      Specification

      1) jni.h will define a new JNI version constant for JDK 10:

      +#define JNI_VERSION_10 0x000a0000

      (Note: the name may be revised per the decision about the version string for the new release cadence discussion [1])

      2) The spec of FindClass is updated to specify the behavior when called from the library lifecycle hooks as follows:

       
      +Since JDK 10, when `FindClass` is called from a library lifecycle function
      +hook the class loader is determined as follows:
      +
      +   * for `JNI_OnLoad` and `JNI_OnLoad_L` the class loader of the class that
      +     is loading the native library is used
      +   * for `JNI_OnUnload` and `JNI_OnUnload_L` the class loader returned by 
      +     `ClassLoader.getSystemClassLoader` is used (as the class loader used
      +      at on-load time may no longer exist) 
      

      3) The spec change for the GetVersion function:

      +In JDK/JRE 10, GetVersion() returns JNI_VERSION_10.

      [1] http://mail.openjdk.java.net/pipermail/discuss/2017-September/004281.html

            mchung Mandy Chung (Inactive)
            mchung Mandy Chung (Inactive)
            Alan Bateman, David Holmes
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: