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

Reduce public exports in dynamic libraries built from JDK static libraries

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 15
    • core-libs
    • None
    • binary, behavioral
    • minimal
    • The only affect this proposed change has is to hide JNI entrypoints that should be hidden and not used in shared libraries produced from JDK static libraries. This configuration is not generally used by average Java developers.
    • Other
    • Implementation

      Summary

      Allow the declaration of JNIEXPORT in jni.h to be overridden in order to allow developers to alter the default visibility of JNI native entrypoint symbols.

      Problem

      All JNI entrypoints that exist in JDK libraries that are built statically are declared as exported or visible. If a dynamic library is built from these static libraries, we end up with many exported symbols even though we don't need or want to provide access to these entrypoints.

      Solution

      Allow the define JNIEXPORT in jni.h to be overridden so that the visibility of JNI native entrypoints can be specified externally. The JDK build will then override JNIEXPORT to inhibit the exporting of JNI function entrypoints in libraries that are statically built.

      Impact

      The impact of this change is two fold. The change to jni.h will allow a developer to override the definition of JNIEXPORT in a source file that includes jni.h and the changes to the JDK build system makes use of the JNIEXPORT change to alter the default symbol visibility for JDK libraries that are built statically via the "make static-libs-image" target.

      The jni.h changes have no impact on the creation of JNI libraries unless a source file defines JNIEXPORT to be something different than the default value specified in the platform specific header files included in jni.h. The expected use of this override is to alter the default attribute value that is used in the default JNIEXPORT definition in order to avoid causing all JNI native entrypoint to be exported in shared libraries.

      The JDK build changes documented in the CSR cause JNIEXPORT to be overriden during the creation of static libraries in order to keep static native library entrypoints from being automatically exported when used to create shared libraries. Other than the jni.h impact described above, a normal JDK distribution is not impacted by these changes since we do not ship static libraries.

      Specification

      diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4
      --- a/make/autoconf/flags-cflags.m4
      +++ b/make/autoconf/flags-cflags.m4
      @@ -709,7 +709,10 @@
         # JDK libraries.
         STATIC_LIBS_CFLAGS="-DSTATIC_BUILD=1"
         if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
      -    STATIC_LIBS_CFLAGS="$STATIC_LIBS_CFLAGS -ffunction-sections -fdata-sections"
      +    STATIC_LIBS_CFLAGS="$STATIC_LIBS_CFLAGS -ffunction-sections -fdata-sections \
      +      -DJNIEXPORT='__attribute__((visibility(\"hidden\")))'"
      +  else
      +    STATIC_LIBS_CFLAGS="$STATIC_LIBS_CFLAGS -DJNIEXPORT="
         fi
         if test "x$TOOLCHAIN_TYPE" = xgcc; then
           # Disable relax-relocation to enable compatibility with older linkers
      diff --git a/src/java.base/unix/native/include/jni_md.h b/src/java.base/unix/native/include/jni_md.h
      --- a/src/java.base/unix/native/include/jni_md.h
      +++ b/src/java.base/unix/native/include/jni_md.h
      @@ -29,16 +29,26 @@
       #ifndef __has_attribute
         #define __has_attribute(x) 0
       #endif
      +
      +#ifndef JNIEXPORT
      +  #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
      +    #ifdef ARM
      +      #define JNIEXPORT     __attribute__((externally_visible,visibility("default")))
      +    #else
      +      #define JNIEXPORT     __attribute__((visibility("default")))
      +    #endif
      +  #else
      +    #define JNIEXPORT
      +  #endif
      +#endif
      +
       #if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
         #ifdef ARM
      -    #define JNIEXPORT     __attribute__((externally_visible,visibility("default")))
           #define JNIIMPORT     __attribute__((externally_visible,visibility("default")))
         #else
      -    #define JNIEXPORT     __attribute__((visibility("default")))
           #define JNIIMPORT     __attribute__((visibility("default")))
         #endif
       #else
      -  #define JNIEXPORT
         #define JNIIMPORT
       #endif
      
      diff --git a/src/java.base/windows/native/include/jni_md.h b/src/java.base/windows/native/include/jni_md.h
      --- a/src/java.base/windows/native/include/jni_md.h
      +++ b/src/java.base/windows/native/include/jni_md.h
      @@ -26,7 +26,9 @@
       #ifndef _JAVASOFT_JNI_MD_H_
       #define _JAVASOFT_JNI_MD_H_
      
      -#define JNIEXPORT __declspec(dllexport)
      +#ifndef JNIEXPORT
      +  #define JNIEXPORT __declspec(dllexport)
      +#endif
       #define JNIIMPORT __declspec(dllimport)
       #define JNICALL __stdcall

            bobv Bob Vandette (Inactive)
            bobv Bob Vandette (Inactive)
            David Holmes, Magnus Ihse Bursie, Tom Rodriguez
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: