Class SoLoader


  • @ThreadSafe
    public class SoLoader
    extends java.lang.Object
    Native code loader.

    To load a native library, call the static method loadLibrary(java.lang.String) from the static initializer of the Java class declaring the native methods. The argument should be the library's short name.

    Note: SoLoader is enabled by default. Application could define com.facebook.soloader.enabled metadata entry to control using SoLoader or System Loader.

    For example, if the native code is in libmy_jni_methods.so:

    
     class MyClass {
       static {
         SoLoader.loadLibrary("my_jni_methods");
       }
     }
     

    Before any library can be loaded SoLoader needs to be initialized. The application using SoLoader should do that by calling SoLoader.init early on app initialization path. The call must happen before any class using SoLoader in its static initializer is loaded.

    An example of the meta data entry to disable SoLoader:

         <application ...>
           <meta-data
               android:name="com.facebook.soloader.enabled"
               android:value="false" />
         </application>
     
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  SoLoader.WrongAbiError  
    • Constructor Summary

      Constructors 
      Constructor Description
      SoLoader()  
    • Method Summary

      Modifier and Type Method Description
      static boolean areSoSourcesAbisSupported()
      This function ensure that every SoSources Abi is supported for at least one abi in SysUtil.getSupportedAbis
      static void deinitForTest()
      Make shared-library loading delegate to the system.
      static java.lang.String[] getLibraryDependencies​(java.lang.String libName)
      Gets the dependencies of a library.
      static java.lang.String getLibraryPath​(java.lang.String libName)
      Gets the full path of a library.
      static int getLoadedLibrariesCount()
      Returns count of already loaded so libraries
      static java.io.File getSoFile​(java.lang.String shortName)
      Returns the so file for the specified library.
      static int getSoSourcesVersion()  
      static void init​(android.content.Context context, boolean nativeExopackage)
      Backward compatibility.
      static void init​(android.content.Context context, int flags)  
      static void init​(android.content.Context context, int flags, SoFileLoader soFileLoader)  
      static void init​(android.content.Context context, int flags, SoFileLoader soFileLoader, java.lang.String[] denyList)
      Initializes native code loading for this app; this class's other static facilities cannot be used until this init(android.content.Context, int) is called.
      static boolean isInitialized()  
      static boolean loadLibrary​(java.lang.String shortName)  
      static boolean loadLibrary​(java.lang.String shortName, int loadFlags)
      Load a shared library, initializing any JNI binding it contains.
      static java.lang.String makeLdLibraryPath()
      Retrieve an LD_LIBRARY_PATH value suitable for using the native linker to resolve our shared libraries.
      static java.lang.String makeNonZipPath​(java.lang.String localLdLibraryPath)  
      static void prependSoSource​(SoSource extraSoSource)
      Add a new source of native libraries.
      static void setInTestMode()
      Turn shared-library loading into a no-op.
      static void setSystemLoadLibraryWrapper​(SystemLoadLibraryWrapper wrapper)
      Provide a wrapper object for calling System.loadLibrary(java.lang.String).
      static java.io.File unpackLibraryAndDependencies​(java.lang.String shortName)
      Unpack library and its dependencies, returning the location of the unpacked library file.
      static boolean useDepsFile​(android.content.Context context, boolean async, boolean extractToDisk)
      Enables the use of a deps file to fetch the native library dependencies to avoid reading them from the ELF files.
      • Methods inherited from class java.lang.Object

        equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • VERSION

        public static java.lang.String VERSION
      • SOLOADER_ENABLE_EXOPACKAGE

        public static final int SOLOADER_ENABLE_EXOPACKAGE
        Enable the exopackage SoSource.
        See Also:
        Constant Field Values
      • SOLOADER_ALLOW_ASYNC_INIT

        public static final int SOLOADER_ALLOW_ASYNC_INIT
        Allow deferring some initialization work to asynchronous background threads. Shared libraries are nevertheless ready to load as soon as init returns.
        See Also:
        Constant Field Values
      • SOLOADER_DISABLE_BACKUP_SOSOURCE

        public static final int SOLOADER_DISABLE_BACKUP_SOSOURCE
        In some contexts, using a backup so source in case of so corruption is not feasible e.g. lack of write permissions to the library path.
        See Also:
        Constant Field Values
      • SOLOADER_SKIP_MERGED_JNI_ONLOAD

        public static final int SOLOADER_SKIP_MERGED_JNI_ONLOAD
        Skip calling JNI_OnLoad if the library is merged. This is necessary for libraries that don't define JNI_OnLoad and are only loaded for their side effects (like static constructors registering callbacks). DO NOT use this to allow implicit JNI registration (by naming your methods Java_com_facebook_whatever) because that is buggy on Android.
        See Also:
        Constant Field Values
      • SOLOADER_DONT_TREAT_AS_SYSTEMAPP

        public static final int SOLOADER_DONT_TREAT_AS_SYSTEMAPP
        System Apps ignore PREFER_ANDROID_LIBS_DIRECTORY. Don't do that for this app.
        See Also:
        Constant Field Values
      • SOLOADER_ENABLE_DIRECT_SOSOURCE

        public static final int SOLOADER_ENABLE_DIRECT_SOSOURCE
        In API level 23 and above, it’s possible to open a .so file directly from your APK. Enabling this flag will explicitly add the direct SoSource in soSource list.
        See Also:
        Constant Field Values
      • SOLOADER_EXPLICITLY_ENABLE_BACKUP_SOSOURCE

        public static final int SOLOADER_EXPLICITLY_ENABLE_BACKUP_SOSOURCE
        For compatibility, we need explicitly enable the backup soSource. This flag conflicts with SOLOADER_DISABLE_BACKUP_SOSOURCE, you should only set one of them or none.
        See Also:
        Constant Field Values
      • SOLOADER_DISABLE_FS_SYNC_JOB

        public static final int SOLOADER_DISABLE_FS_SYNC_JOB
        Experiment ONLY: disable the fsync job in soSource
        See Also:
        Constant Field Values
    • Constructor Detail

      • SoLoader

        public SoLoader()
    • Method Detail

      • init

        public static void init​(android.content.Context context,
                                int flags)
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • init

        public static void init​(android.content.Context context,
                                int flags,
                                @Nullable
                                SoFileLoader soFileLoader)
                         throws java.io.IOException
        Throws:
        java.io.IOException
      • init

        public static void init​(android.content.Context context,
                                int flags,
                                @Nullable
                                SoFileLoader soFileLoader,
                                java.lang.String[] denyList)
                         throws java.io.IOException
        Initializes native code loading for this app; this class's other static facilities cannot be used until this init(android.content.Context, int) is called. This method is idempotent: calls after the first are ignored.
        Parameters:
        context - application context
        flags - Zero or more of the SOLOADER_* flags
        soFileLoader - the custom SoFileLoader, you can implement your own loader
        denyList - Skip load libs from system soSource, due to the linker namespace restriction
        Throws:
        java.io.IOException - IOException
      • init

        public static void init​(android.content.Context context,
                                boolean nativeExopackage)
        Backward compatibility.
        Parameters:
        context - application context
        nativeExopackage - pass SOLOADER_ENABLE_EXOPACKAGE as flags if true
        See Also:
        What is exopackage?
      • setInTestMode

        public static void setInTestMode()
        Turn shared-library loading into a no-op. Useful in special circumstances.
      • deinitForTest

        public static void deinitForTest()
        Make shared-library loading delegate to the system. Useful for tests.
      • setSystemLoadLibraryWrapper

        public static void setSystemLoadLibraryWrapper​(SystemLoadLibraryWrapper wrapper)
        Provide a wrapper object for calling System.loadLibrary(java.lang.String). This is useful for controlling which ClassLoader libraries are loaded into.
        Parameters:
        wrapper - the wrapper you wanna set
      • getLibraryPath

        @Nullable
        public static java.lang.String getLibraryPath​(java.lang.String libName)
                                               throws java.io.IOException
        Gets the full path of a library.
        Parameters:
        libName - the library file name, including the prefix and extension.
        Returns:
        the full path of the library, or null if it is not found in none of the SoSources.
        Throws:
        java.io.IOException - if there is an error calculating the canonical path of libName
      • getLibraryDependencies

        @Nullable
        public static java.lang.String[] getLibraryDependencies​(java.lang.String libName)
                                                         throws java.io.IOException
        Gets the dependencies of a library.
        Parameters:
        libName - the library file name, including the prefix and extension.
        Returns:
        An array naming the dependencies of the library, or null if it is not found in any SoSources
        Throws:
        java.io.IOException - if there is an error reading libName
      • getSoFile

        @Nullable
        public static java.io.File getSoFile​(java.lang.String shortName)
        Returns the so file for the specified library. Returns null if the library does not exist or if it's not backed by a file.
        Parameters:
        shortName - Name of library to find, without "lib" prefix or ".so" suffix
        Returns:
        the File object of the so file
      • loadLibrary

        public static boolean loadLibrary​(java.lang.String shortName)
      • loadLibrary

        public static boolean loadLibrary​(java.lang.String shortName,
                                          int loadFlags)
                                   throws java.lang.UnsatisfiedLinkError
        Load a shared library, initializing any JNI binding it contains.
        Parameters:
        shortName - Name of library to find, without "lib" prefix or ".so" suffix
        loadFlags - Control flags for the loading behavior. See available flags under SoSource (LOAD_FLAG_XXX).
        Returns:
        Whether the library was loaded as a result of this call (true), or was already loaded through a previous call to SoLoader (false).
        Throws:
        java.lang.UnsatisfiedLinkError
      • unpackLibraryAndDependencies

        public static java.io.File unpackLibraryAndDependencies​(java.lang.String shortName)
                                                         throws java.lang.UnsatisfiedLinkError
        Unpack library and its dependencies, returning the location of the unpacked library file. All non-system dependencies of the given library will either be on LD_LIBRARY_PATH or will be in the same directory as the returned File.
        Parameters:
        shortName - Name of library to find, without "lib" prefix or ".so" suffix
        Returns:
        Unpacked DSO location
        Throws:
        java.lang.UnsatisfiedLinkError
      • makeNonZipPath

        @Nullable
        public static java.lang.String makeNonZipPath​(java.lang.String localLdLibraryPath)
      • isInitialized

        public static boolean isInitialized()
      • getSoSourcesVersion

        public static int getSoSourcesVersion()
      • prependSoSource

        public static void prependSoSource​(SoSource extraSoSource)
                                    throws java.io.IOException
        Add a new source of native libraries. SoLoader consults the new source before any currently-installed source.
        Parameters:
        extraSoSource - The SoSource to install
        Throws:
        java.io.IOException - IOException
      • makeLdLibraryPath

        public static java.lang.String makeLdLibraryPath()
        Retrieve an LD_LIBRARY_PATH value suitable for using the native linker to resolve our shared libraries.
        Returns:
        the LD_LIBRARY_PATH in string
      • areSoSourcesAbisSupported

        public static boolean areSoSourcesAbisSupported()
        This function ensure that every SoSources Abi is supported for at least one abi in SysUtil.getSupportedAbis
        Returns:
        true if all SoSources have their Abis supported
      • useDepsFile

        public static boolean useDepsFile​(android.content.Context context,
                                          boolean async,
                                          boolean extractToDisk)
        Enables the use of a deps file to fetch the native library dependencies to avoid reading them from the ELF files. The file is expected to be in the APK in assets/native_deps.txt. Returns true on success, false on failure. On failure, dependencies will be read from ELF files instead of the deps file.
        Parameters:
        context - - Application context, used to find native deps file in APK
        async - - If true, initialization will occur in a background thread and we library loading will wait for initialization to complete.
        extractToDisk - - If true, the native deps file will be extract from the APK and written to disk. This can be useful when the file is compressed in the APK, since we can prevent decompressing the file every time.
        Returns:
        True if initialization succeeded, false otherwise. Always returns true if async is true.
      • getLoadedLibrariesCount

        public static int getLoadedLibrariesCount()
        Returns count of already loaded so libraries
        Returns:
        number of loaded libraries