realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.45k stars 1.75k forks source link

Missing library `librealm-jni.so` #7797

Open clementetb opened 1 year ago

clementetb commented 1 year ago

This ticket tracks any issues and developments about the SDK being unable to resolve the native library during the initialization phase.

The issue occurs when an exception is thrown while invoking Realm.init(context) with the following stacktrace:

Caused by j8.b: Could not find 'librealm-jni.so'. Looked for: [arm64-v8a, armeabi-v7a, armeabi], but only found: [].
at com.getkeepsafe.relinker.ApkLibraryInstaller.installLibrary(ApkLibraryInstaller.java:173)
at com.getkeepsafe.relinker.ReLinkerInstance.loadLibraryInternal(ReLinkerInstance.java:180)
at com.getkeepsafe.relinker.ReLinkerInstance.loadLibrary(ReLinkerInstance.java:136)
at com.getkeepsafe.relinker.ReLinker.loadLibrary(ReLinker.java:70)
at com.getkeepsafe.relinker.ReLinker.loadLibrary(ReLinker.java:57)
at io.realm.internal.RealmCore.loadLibrary(RealmCore.java:60)
at io.realm.Realm.initializeRealm(Realm.java:348)
at io.realm.Realm.init(Realm.java:263)

There is not a clear cause for it. It might be related to Relinker, or the app distributable not containing the artifacts for the device architecture.

The following issues report this same bug:

Works related to this:

haytham-c01 commented 9 months ago

We are also getting reports of the crash occurring 4,168 times across 276 users in the last 90 days on various devices (Huawei, Samsung, Oppo, Xiaomi, Transmission, Nexus, and possibly others) and various Android versions (7, 8, 9, 10, 11, 12, 13) as reported by Firebase Crashlytics. All of these occurrences are from the users who have sideloaded the app, i.e., installed the app through APK from sources outside Google’s Play Store.

I have managed to reproduce a similar crash (com.getkeepsafe.relinker.MissingLibraryException: librealm-jni.so) by downloading an XAPK file from APK Combo, decompressing/unzipping it into APKs, and installing the base APK only.

clementetb commented 9 months ago

@haytham-c01 Did the XAPK file contain the librealm-jni.so for all platforms?

haytham-c01 commented 9 months ago

@cmelchior Yes, but only in the config/split APKs and not the base APK I installed.

haytham-c01 commented 9 months ago

More importantly, I reproduced a more common version of the crash by using an APK generated by APK extraction apps, namely:

The resulting APK was missing the libs folder which is supposed to contain .so files. These tools seem to fail to extract a valid APK from the apps installed from AAB, yet work fine with the apps installed from APK.

The error I got when installing the extracted APK is: com.getkeepsafe.relinker.MissingLibraryException: Could not find 'librealm-jni.so'. Looked for: [arm64-v8a], but only found: []

haytham-c01 commented 9 months ago

Note: I am describing the result of my investigation and manual testing. I haven't tried the solution on our production app and I don't know if we would want to try it. I hope it helps :)

Summary

The problem

APK extraction apps are not handling app bundles, thus, creating incomplete APKs without .so files, therefore, the installed apps crash.

The Solution

Ideally, these APK extraction apps should either handle app bundles or tell the user that the select app is not supported.

A less ideal solution from our side is to either revert to publishing APKs instead of app bundles or disable splits on app bundles:

bundle {
        language {
            enableSplit = false
        }
        abi {
            enableSplit = true
        }
        density {
            enableSplit = true
        }
        texture {
            enableSplit = false
        }
    }

HOWEVER, in both solutions, we will lose the benefits of app bundles and increase our APK size.

More Details

The problem

I did a quick check on the source code for APK Analyzer, the most downloaded APK extraction app. It seems like it's copying the base APK only and not the split/config APKS, resulting in an APK without the libs folder containing the .so files.

In that app code, there is a reference to applicationInfo.sourceDir, which refers to the base APK in the class AppGeneralDataManager, but no reference to applicationInfo.splitSourceDirs, which refers to the split/config APKs. Therefore, I am assuming app bundles are not handled.

Background Info

Apps that are installed from the app bundle generate multiple APKs in the path data/app, which can be seen in Android Studio's device explorer with root access. One of these APKs is a base APK, and the rest are split/configuration APKS, the configuration APK for ABI contains the libs folder and thus the .so files.

To test both install types, open the "run" dropdown menu, then click on "edit configurations", then select from "deploy": image

Here is what data/app looks like when installing from APK vs Bundle:

APK Bundle
image 289535546-aa592933-a8b6-43c5-9543-f7ada2e1faa8
chk2902 commented 2 weeks ago

Unfortunately, this came in today from a Kindle Fire user::

Caused by: com.getkeepsafe.relinker.MissingLibraryException: Could not find 'librealm-jni.so'. Looked for: [arm64-v8a, armeabi-v7a, armeabi], but only found: [].
    at com.getkeepsafe.relinker.ApkLibraryInstaller.installLibrary(ApkLibraryInstaller.java:173)
    at com.getkeepsafe.relinker.ReLinkerInstance.loadLibraryInternal(ReLinkerInstance.java:180)
    at com.getkeepsafe.relinker.ReLinkerInstance.loadLibrary(ReLinkerInstance.java:136)
    at com.getkeepsafe.relinker.ReLinker.loadLibrary(ReLinker.java:70)
    at com.getkeepsafe.relinker.ReLinker.loadLibrary(ReLinker.java:57)
    at io.realm.internal.RealmCore.loadLibrary(RealmCore.java:60)
    at io.realm.Realm.initializeRealm(Realm.java:348)
    at io.realm.Realm.init(Realm.java:263)

ANDROID_VERSION=11 PHONE_MODEL=KFRAWI

realm_version = '10.18.0'