1

I have a unity project configured to be a dynamic feature module. This installs perfectly fine on-demand. But when I run it, the app crashes with following error:

JNI FatalError called: Unable to load library: /data/app/com.example.app-8fx1RRZrQ34BcwXf8ajjqZ==/lib/arm64/libunity.so [dlopen failed: library "libunity.so" not found]

The target activity of the Unity project includes SplitCompat.install(this);

And it's gradle looks like:

    // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN

    buildscript {
        repositories {
            mavenCentral()
            google()
            jcenter()
        }

        dependencies {
            classpath 'com.android.tools.build:gradle:3.5.0'
        }
    }

    allprojects {
        repositories {
            mavenCentral()
            google()
            jcenter()
            flatDir {
                dirs 'libs'
            }
        }
    }

    apply plugin: 'com.android.dynamic-feature'

    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    }

    android {
        compileSdkVersion rootProject.compileSdk
        buildToolsVersion rootProject.buildTools

        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }

        defaultConfig {
            minSdkVersion rootProject.minSdk
            targetSdkVersion rootProject.targetSdk
            versionCode rootProject.versionCode
            versionName rootProject.versionName

            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
            }
        }

        lintOptions {
            abortOnError false
        }

        aaptOptions {
            noCompress = ['.unity3d', '.ress', '.resource', '.obb']
        }

        flavorDimensions "default"

        productFlavors {
            staging {
                dimension "default"
            }

            production {
                dimension "default"
            }

            develop {
                dimension "default"
            }
        }

        compileOptions {
            sourceCompatibility 1.8
            targetCompatibility 1.8
        }

        buildTypes {
            debug {
                minifyEnabled false
                useProguard false
                jniDebuggable true
            }
            release {
                minifyEnabled false
                useProguard false
            }
        }

        packagingOptions {
            doNotStrip '*/armeabi-v7a/*.so'
            doNotStrip '*/arm64-v8a/*.so'
    //        doNotStrip '*/x86/*.so'
        }

    }

    dependencies {
        implementation project(':app')
    }

While the gradle of app module has:

    bundle {
        language {
            // Specifies that the app bundle should not support
            // configuration APKs for language resources. These
            // resources are instead packaged with each base and
            // dynamic feature APK.
            enableSplit = false
        }
        density {
            // This property is set to true by default.
            enableSplit = false
        }
        abi {
            // This property is set to true by default.
            enableSplit = true
        }
    }

I even tried disabling the .so compression by setting android.bundle.enableUncompressedNativeLibs = false in gradle.properties file, but the exact error persists.

Internals of the feature module as seen in the aab. The .so libs are present:

Internals of the feature module as seen in the aab. The .so libs are present

How may I resolve this?

Update 1 -

The problem i've described above occurs when the aab is installed from play store for the first time. Note that I am able to successfully install the feature module and the error occurs only when I attempt to run it. However, when I push an incremental update over the same installation, the feature module is somehow able to work flawlessly and is able to find the necessary .so file. I've tried these steps several times on repeat to validate the observation.

rajagrawal
  • 622
  • 4
  • 14
  • 26
  • You have library **libunity.so** *not found* Remember an **apk** is just a **zip** file, so **unzip** it and check if the **ibunity.so** is in **/lib/arm64/** – Jon Goodwin Sep 21 '19 at 08:43
  • IC I suggest you read about [aab](https://fileinfo.com/extension/aab) and try [bundletool](https://developer.android.com/studio/command-line/bundletool) – Jon Goodwin Sep 21 '19 at 15:11
  • Common causes of the problem you describe are: proguard,manual lib missing/in the wrong place (paths), gradle-lib- copy required (paths)...tweek your question, put some effort in, what goes where, file layouts (directory trees) See my answer [here](https://stackoverflow.com/questions/47167769/hello-world-android-app-with-as-few-files-as-possible-no-ide-and-text-editor/47251607#47251607) to show you a way to do it – Jon Goodwin Sep 22 '19 at 02:51
  • Probably a simple fix but not enough info, put more effort in **"And it's gradle looks like:"** which ? 1 File 2 files ? Where are they (relative paths). **"While the gradle of app module has:"**. Be specific. Probable fixes: proguard, lib paths... – Jon Goodwin Sep 22 '19 at 02:56
  • Hi @JonGoodwin, i'm aware that the apks and aabs are essentially zipped packages. I've updated my query and attached a screenshot for the dynamic feature's internals. I've also extracted the apks with the bundletool and I can see the .so libs are generated. The gradle file contents i've shared above belong to unityProj.gradle and app.gradle respectively (not one at the root level, which won't be useful here). – rajagrawal Sep 24 '19 at 07:15
  • Which phone are you using for testing? Have you tried any other phone with armeabi-v7a arch? – shingo Sep 24 '19 at 08:15
  • @shingo Yes! I've tested this on OnePlus 5 which is arm64, and one old Samsung device with Kitkat, which I presume to be arm7. – rajagrawal Sep 24 '19 at 13:12
  • On the samsung is the error still at arm64 folder or not? – shingo Sep 24 '19 at 13:57
  • @shingo The error persists on Samsung device too. – rajagrawal Sep 24 '19 at 14:49
  • Seems you've fixed your loading problem ? For your **Failed to extract resources needed by Il2CPP** it maybe **ERROR MESSAGE WHEN LOCAL STORAGE IS FULL** see [issuetracker.unity3d.com issue 1171893](https://issuetracker.unity3d.com/issues/custom-failed-to-extract-resources-needed-by-il2cpp-error-message-when-local-storage-is-full) – Jon Goodwin Sep 26 '19 at 12:53

2 Answers2

2

Make sure the unity library is loaded using SplitCompat in your dynamic feature modules: https://developer.android.com/guide/app-bundle/playcore#load_native_libs

I'm not sure if this is handled automatically by Unity, but if it is you might want to reach out to them to address this.

Pierre
  • 15,865
  • 4
  • 36
  • 50
  • 1
    I've tried this earlier without success, but re-attempting now helped move on. Turns out loadLibrary("") strictly takes the library "name" which should exclude "lib" and ".so". But now I see another error as UnityActivity loads - **Failed to extract resources needed by Il2CPP.** This is persistent across several test devices. UnityActivity has SplitCompat.install(this). – rajagrawal Sep 26 '19 at 05:14
  • This looks independent of DFM. Does it work when you don't use DFM? – Pierre Sep 26 '19 at 09:01
  • I suspect too. It works fine when integrated as simple module in the project. The issue is only when DFM comes in picture. – rajagrawal Sep 26 '19 at 11:31
  • Is there any activity in the DFM? – Pierre Sep 26 '19 at 15:12
  • Yes, the unity module (which is the DFM) has an activity that I launch from the base module. So the flow is - I install the DFM (Unity module), load the unity libraries, then launch the UnityActivity. – rajagrawal Sep 26 '19 at 19:02
  • A quick internet search for that error suggests that this might be related to storage or memory issue. If you really think this is a bug related to DFM then you may want to file a bug on Unity issue tracker with a sample app that reproduces the issue. – Pierre Sep 26 '19 at 20:21
  • Hi @rajagrawal - I am facing the same problem as you, I have added System.loadLibrary("libunity") when clicking on load DFM (before checking for DFM), but i am still not able to resolve it. Are you able to make it work using the above-discussed methods? If not please help me with how we can solve it. – Kartik Shah Sep 27 '21 at 18:49
  • Never mind I have resolved my issue by adding System.loadLibrary("unity") before loading the library and it works smoothly. for those who are not from a java background: to use System.loadLibrary you have to import class java.lang.Runtime – Kartik Shah Sep 29 '21 at 05:43
0

I was also seeing "JNI Fatal Error called: Unable to load library .../libunity.so" in log files.

In my case, I noticed that Unity logged an error about not being able to read the bin/Data/settings.xml file. I added those directories and the file to my project's assets and then the libunity library was able to load. So even though you may see a message saying the libunity.so file was not found, the problem is really that the unity library was not able to initialize properly.

John Weidner
  • 2,055
  • 3
  • 18
  • 31
  • Ran into this once after upgrading the version of gradle I was using. Switched back to an older gradle and the problem went away. I haven't had time to research why this was happening. – John Weidner Apr 22 '21 at 21:23
  • I came to an "assumed" conclusion that Unity doesn't support abi splits. We (the company I used to work at) dropped the idea of using Unity and went with native implementation instead. Haven't heard anything from Unity support since I last posted this issue on their forum. – rajagrawal Sep 28 '21 at 12:20