Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libobjectbox-jni.so not found on Android 6 and older #369

Closed
alsoLut opened this issue Jan 20, 2022 · 30 comments
Closed

libobjectbox-jni.so not found on Android 6 and older #369

alsoLut opened this issue Jan 20, 2022 · 30 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@alsoLut
Copy link

alsoLut commented Jan 20, 2022

Invalid argument(s): Failed to load dynamic library 'libobjectbox-jni.so': dlopen failed: library "libobjectbox-jni.so" not found

  • ObjectBox version: 1.3.0
  • Flutter/Dart SDK: 2.8.1
  • Null-safety enabled: yes
  • Reproducibility: always
  • OS: Android 6
@alsoLut alsoLut added the bug Something isn't working label Jan 20, 2022
@greenrobot-team
Copy link
Member

Thanks, but I can't reproduce this (using Android emulator). Could you share more details about the project, maybe even a small example project? Also what devices are you trying to run it on?

@greenrobot-team
Copy link
Member

Closing this issue due to inactivity. 💤 Feel free to comment with more details or submit a new issue.

@quewen08
Copy link

quewen08 commented Jun 13, 2022

I have same question in android Marshmallow(API 23) device
Here is my option:

app/build.gradle

android {
...
    sourceSets {
        main() {
            java.srcDirs += 'src/main/kotlin'
            jni.srcDirs = []
            jniLibs.srcDirs = ['libs']
            res.srcDirs = ['src/main/res']
        }
    }

    defaultConfig {
        ...
        ndk {
            abiFilters 'arm64-v8a', 'x86_64', 'armeabi-v7a'
        }     
        ...
    }
...
}

flutter doctor

[√] Flutter (Channel unknown, 2.10.5, on Microsoft Windows [Version 10.0.19044.1741], locale zh-CN)
    • Flutter version 2.10.5 at
    • Upstream repository unknown
    • Framework revision 5464c5bac7 (8 weeks ago), 2022-04-18 09:55:37 -0700
    • Engine revision 57d3bac3dd
    • Dart version 2.16.2
    • DevTools version 2.9.2
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn
[√] Android Studio (version 2021.2)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)

......
dependencies:
  ......
  #db
  objectbox: ^1.5.0
  objectbox_flutter_libs: any
  ......

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^1.0.0
  build_runner: ^2.1.11
  objectbox_generator: any
......

// splash_controller.dart
......
  @override
  void onReady() {
    super.onReady();
   ...
   _store = await openStore().catchError((e) {
        throw e;
    });
   ...
  }
......

I/flutter (17898): Failed to load ObjectBox library. For Flutter apps, check if objectbox_flutter_libs is added to dependencies. For unit tests and Dart apps, check if the ObjectBox library was downloaded (https://docs.objectbox.io/getting-started).
E/flutter (17898): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'libobjectbox-jni.so': dlopen failed: library "libobjectbox-jni.so" not found
E/flutter (17898): #0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:12:43)
E/flutter (17898): #1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:23:12)
E/flutter (17898): #2      _tryObjectBoxLibFile (package:objectbox/src/native/bindings/bindings.dart:77:29)
E/flutter (17898): #3      loadObjectBoxLib (package:objectbox/src/native/bindings/bindings.dart:94:12)
E/flutter (17898): #4      C (package:objectbox/src/native/bindings/bindings.dart:112:27)
E/flutter (17898): #5      C (package:objectbox/src/native/bindings/bindings.dart)
E/flutter (17898): #6      new Model (package:objectbox/src/native/model.dart:19:31)
E/flutter (17898): #7      new Store (package:objectbox/src/native/store.dart:117:21)
E/flutter (17898): #8      openStore (package:xxxxxx/objectbox.g.dart:276:5)
E/flutter (17898): <asynchronous suspension>
E/flutter (17898): #9      SplashController.onReady.<anonymous closure> (package:xxxxxx/pages/splash/splash_controller.dart:30:16)
E/flutter (17898): <asynchronous suspension>
E/flutter (17898): 

@greenrobot-team
Copy link
Member

@quewen08 Can you analyze your APK or AAB file (e.g. open it with Android Studio) and make sure the libobjectbox-jni.so exists?

@quewen08
Copy link

Sure I have
image

@greenrobot-team
Copy link
Member

greenrobot-team commented Jun 14, 2022

This appears to be an issue on Android 6 and older and can possibly be solved by loading the library in Java, then trying again to load the library in Dart: simolus3/drift#895

Now I also see why #328 makes sense (though would not do this for all devices, only if users actively call a workaround method, e.g. like sqlite3_flutter_libs or if the code could detect it's running on Android 6 or older).

@quewen08 Can you check what version of the Android Gradle Plugin is used in your project? And maybe try updating to the latest version? Are you building APKs or App Bundles? I remember the Gradle plugin receiving some fixes so native libraries are extracted on Android 6 devices, which should avoid this issue.

@greenrobot-team greenrobot-team removed the more info required Needs more info to become actionable. Auto-closed if no response. label Jun 14, 2022
@quewen08
Copy link

I think my gradle version is enough

android/build.gradle

buildscript{
...
    dependencies {
        classpath 'com.android.tools.build:gradle:7.1.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
...
}

gradle/wrapper/gradle-wrapper.properties

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip

@greenrobot-team
Copy link
Member

@quewen08 Version 7.1.2 looks recent enough.

You may try the suggestion about targeting Android 6.0 in the warning at https://docs.flutter.dev/deployment/android#building-the-app-for-release

@quewen08
Copy link

@quewen08 Version 7.1.2 looks recent enough.

You may try the suggestion about targeting Android 6.0 in the warning at https://docs.flutter.dev/deployment/android#building-the-app-for-release

Hum, it seems useless. I tried add android.bundle.enableUncompressedNativeLibs=false in android/gradle.properties ,then I checked the AndroidManifest.xml, make sure it does not has android:extractNativeLibs=false in the <application> tag. And then I run it on my device, it also cannot get the libobjectbox-jni.so.

@greenrobot-team
Copy link
Member

greenrobot-team commented Jun 21, 2022

@quewen08 Thanks for trying! Then we probably have to add the workaround as described in my previous comment to a future release.

(Note for me: see internal issue for details.)

@mdpe-ir
Copy link

mdpe-ir commented Jul 28, 2022

I had the same problem and I solved it:

edit :

import 'objectbox.g.dart'; // created by `flutter pub run build_runner build`

class ObjectBox {
  /// The Store of this app.
  late final Store store;
  
  ObjectBox._create(this.store) {
    // Add any additional setup code, e.g. build queries.
  }

  /// Create an instance of ObjectBox to use throughout the app.
  static Future<ObjectBox> create() async {
    // Future<Store> openStore() {...} is defined in the generated objectbox.g.dart
    final store = await openStore();
    return ObjectBox._create(store);
  }
}

and changed it to :

 /// Create an instance of ObjectBox to use throughout the app.
  static Future<ObjectBox> create() async {
    try {
      final store = await openStore();
      return ObjectBox._create(store);
    } catch (e) {
      PackageInfo packageInfo = await PackageInfo.fromPlatform();
      DynamicLibrary.open("/data/data/${packageInfo.packageName}/lib/libobjectbox-jni.so");
      final store = await openStore();
      return ObjectBox._create(store);
    }
  }

--

What happened?

Well, if libobjectbox-jni.so could not load by https://github.com/objectbox/objectbox-dart/blob/main/flutter_libs/android/src/main/java/io/objectbox/objectbox_flutter_libs/ObjectboxFlutterLibsPlugin.java , DynamicLibrary.open("/data/data/${packageInfo.packageName}/lib/libobjectbox-jni.so"); will be load it manually with dart:ffi.

@greenrobot-team greenrobot-team added this to the 1.6.1 milestone Aug 1, 2022
@greenrobot-team greenrobot-team modified the milestones: 1.6.1, 1.6.2, 1.6.3 Aug 22, 2022
@mariovtor
Copy link

mariovtor commented Nov 2, 2022

#369 (comment)

didnt work here

@kennir
Copy link

kennir commented Nov 11, 2022

#369 (comment)

sorry, did not work, the app stuck on second load

@greenrobot-team
Copy link
Member

@mariovitor @kennir Are both of you trying to work with Android 6 devices? If not, could you please share what devices you are trying this on?

@mariovtor
Copy link

mariovtor commented Nov 14, 2022

@mariovitor @kennir Are both of you trying to work with Android 6 devices? If not, could you please share what devices you are trying this on?

Yes, Android 6 device. I fixed using Kotlin

In MainActivity.kt:

class MainActivity: FlutterActivity() {
    private val CHANNEL = "native_lib_dir"

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
                call, result ->
            if (call.method == "loadNativeLibrary") {

                try {
                    System.loadLibrary("objectbox-jni")
                    result.success("ok")
                } catch (e: Throwable){
                    result.error("error on loading ${e.toString()}",null, null)
                }
            } else {
                result.notImplemented()
            }
         }
      }
   }

created a method

loadNativeObjBoxLib() async {
     const channel = MethodChannel("native_lib_dir");
    return await channel.invokeMethod("loadNativeLibrary");
  }

Put openStore() in a try/catch

Future<void> create() async {
      try {
      store = await openStore();
      } catch (e) {

        if (Platform.isAndroid) {
          try {
          await loadNativeObjBoxLib();
          store = await openStore();
          } catch (e) {
          log('error on object box objectbox $e');
          }
          } else {
          log('error on object box objectbox $e');
          }
        }
       }
   

@kennir
Copy link

kennir commented Nov 15, 2022

@mariovitor @kennir Are both of you trying to work with Android 6 devices? If not, could you please share what devices you are trying this on?

No, this is an android 5.1 device, I will try @mariovitor's solution later

@greenrobot-team greenrobot-team modified the milestones: 1.7.0, 1.7.1 Dec 14, 2022
@greenrobot-team greenrobot-team removed this from the 1.7.1 milestone Jan 24, 2023
@ChickenF622

This comment was marked as resolved.

@mariovtor

This comment was marked as resolved.

@greenrobot-team

This comment was marked as resolved.

@ChickenF622

This comment was marked as resolved.

@greenrobot-team greenrobot-team changed the title libobjectbox-jni.so not found libobjectbox-jni.so not found on Android 6 and older May 9, 2023
@greenrobot-team greenrobot-team added this to the 2.1.1 milestone Jun 20, 2023
@greenrobot-team greenrobot-team self-assigned this Jun 20, 2023
@greenrobot-team
Copy link
Member

greenrobot-team commented Jun 20, 2023

I just released a preview release objectbox: ^2.1.1-dev.2 which contains a new loadObjectBoxLibraryAndroidCompat() method in objectbox_flutter_libs (and objectbox_sync_flutter_libs).

If you are affected, it would help us if you could test if calling it before using any ObjectBox APIs resolves this issue on Android 6 devices (or older). E.g. something like:

Future<void> main() async {
  // This is required so ObjectBox can get the application directory
  // to store the database in.
  WidgetsFlutterBinding.ensureInitialized();

  // Fix to load library on Android 6 devices (or older)
  loadObjectBoxLibraryAndroidCompat();
  objectbox = await ObjectBox.create();

  runApp(const MyApp());
}

If successful, we might consider calling this by default when e.g. using the openStore helper method for Flutter apps (it will only run on Android 6 or older devices).

@greenrobot-team greenrobot-team pinned this issue Jul 11, 2023
@Tumist76
Copy link

Tumist76 commented Aug 3, 2023

@greenrobot-team, hello! We are affected by this issue and tried to switch to 2.1.1-dev.2. I can tell for now that during coarse testing we've encountered no issues. We'd like to handle the issue but we don't want to use a non-release version. Could you please tell when you're planning to make a new release this this fix included?

@greenrobot
Copy link
Member

If successful, we might consider calling this by default when e.g. using the openStore helper method for Flutter apps (it will only run on Android 6 or older devices).

@Tumist76 and others: do you think that's worth that we put in some effort to call this automatically? (I'm a bit surprised to see Android 6 is still supported by app devs.)

@Tumist76
Copy link

Tumist76 commented Aug 4, 2023

@Tumist76 and others: do you think that's worth that we put in some effort to call this automatically? (I'm a bit surprised to see Android 6 is still supported by app devs.)

If there isn't any downsides, I think it'll be better to call this automatically so library usage is identical for those who support Android 6 and for those who don't.

As for Android 6 support altogether - well, it's not like we want to support it, but it still has userbase so we're trying to cover it :)

@greenrobot
Copy link
Member

Just curious, what's the percentage of your users on Android 6?

@Tumist76
Copy link

Tumist76 commented Aug 4, 2023

Really sorry, but I can't disclose this info. Let's just say that'll probably be cheaper to buy these users newer phones than for us to support Android 6 :)

@greenrobot-team
Copy link
Member

We have released version 2.2.0 which includes the compat method mentioned above. Please update using flutter pub upgrade (or dart pub upgrade for Dart Native projects).

Let us know if this fixes the issue on Android 6 and 5 devices. If so, we will consider calling the compat method automatically on these devices in a future release.

@Tumist76
Copy link

Thank you for fast release! We've updated our app to use 2.2.0 in test environments. I'll let you know in about a week, if everything's okay after testing.

@Tumist76
Copy link

Reporting back. We've passed the tests everything's fine on both Android 6.0 and later versions. We didn't test <Android 6.0 though.

@greenrobot-team
Copy link
Member

With the latest release (2.5.0) the workaround is called automatically when using the generated openStore() helper (requires to re-run dart run build_runner build). In this case you can remove the duplicate call from your code.

@greenrobot-team greenrobot-team modified the milestones: 2.2.0, 2.4.1 Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

9 participants