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

library "libsqlitejdbc.so" not found on Android #797

Closed
jrjohn opened this issue Oct 17, 2022 · 14 comments
Closed

library "libsqlitejdbc.so" not found on Android #797

jrjohn opened this issue Oct 17, 2022 · 14 comments
Labels
documentation released Issue has been released

Comments

@jrjohn
Copy link

jrjohn commented Oct 17, 2022

Describe the bug
Run on the android platform will issue this bug

To Reproduce
Connect SQLite DB with sqlite-jdbc from the Android platform.

Logs
2022-10-12 11:27:01.122 16877-16877/com.demo.sqlite E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.demo.sqlite, PID: 16877
java.lang.UnsatisfiedLinkError: dlopen failed: library "libsqlitejdbc.so" not found
at java.lang.Runtime.loadLibrary0(Runtime.java:1077)
at java.lang.Runtime.loadLibrary0(Runtime.java:998)
at java.lang.System.loadLibrary(System.java:1656)
at org.sqlite.core.NativeDB.(NativeDB.java:40)
at org.sqlite.core.NativeDB.load(NativeDB.java:60)
at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:281)
at org.sqlite.SQLiteConnection.(SQLiteConnection.java:68)
at org.sqlite.jdbc3.JDBC3Connection.(JDBC3Connection.java:28)
at org.sqlite.jdbc4.JDBC4Connection.(JDBC4Connection.java:19)
at org.sqlite.JDBC.createConnection(JDBC.java:104)
at org.sqlite.SQLiteConfig.createConnection(SQLiteConfig.java:108)

Environment (please complete the following information):
OS: [Android 12]
CPU architecture: [aarch64]
sqlite-jdbc version [3.39.3.0]

Additional context
About Android ABI description:
https://developer.android.com/ndk/guides/abis

image

The android native library directory name needs to be corrected.
/org/sqlite/native/Linux-Android
aarch64 -> arm64-v8a
arm -> armeabi-v7a
x86
x86_64

I have tested it, It's working now on Android.

@jrjohn jrjohn added the triage label Oct 17, 2022
@gotson
Copy link
Collaborator

gotson commented Oct 17, 2022

The android native library directory name needs to be corrected. /org/sqlite/native/Linux-Android aarch64 -> arm64-v8a arm -> armeabi-v7a x86 x86_64

I have tested it, It's working now on Android.

Can you clarify, i don't understand

@jrjohn
Copy link
Author

jrjohn commented Oct 17, 2022

About android native library https://developer.android.com/studio/projects/add-native-code
image
need rename directory aarch64 to arm64-v8a
and
rename directory arm to armeabi-v7a

Then android loads the native library from arm64-v8a if the android MCU is aarch64 type.
The android system will not load the native library from aarch64 directory.

The source from sqlite-jdbc GitHub android native directory as follow:
jrjohn@Chiende-MacBook-Pro-3 Linux-Android % pwd
/Users/jrjohn/Downloads/org/sqlite/native/Linux-Android
jrjohn@Chiende-MacBook-Pro-3 Linux-Android % ls
aarch64 arm x86 x86_64
jrjohn@Chiende-MacBook-Pro-3 Linux-Android %

@gotson
Copy link
Collaborator

gotson commented Oct 17, 2022

The link you provided doesn't explain anything about the directories.

The directory names in sqlite-jdbc are used to perform a lookup depending on the OS/arch detected, then the corresponding native library is copied to a temp directory.

I don't see how changing the directories where the native lib is stored would change anything.

@jrjohn
Copy link
Author

jrjohn commented Oct 17, 2022

https://developer.android.com/ndk/guides/abis#gradle

ABI management on the Android platform
This section provides details about how the Android platform manages native code in APKs.

Native code in app packages
Both the Play Store and Package Manager expect to find NDK-generated libraries on filepaths inside the APK matching the following pattern:

/lib/"abi name"/lib.so. <====== this is reason

Here, is one of the ABI names listed under Supported ABIs, and is the name of the library as you defined it for the LOCAL_MODULE variable in the Android.mk file. Since APK files are just zip files, it is trivial to open them and confirm that the shared native libraries are where they belong.

@jrjohn
Copy link
Author

jrjohn commented Oct 17, 2022

image
Current ABI name-only support:

armeabi-v7a
arm64-v8a
x86
x86_64

@jrjohn
Copy link
Author

jrjohn commented Oct 17, 2022

I don't think the issue Android UnsatisfiedLinkError #248 is done.

@gotson
Copy link
Collaborator

gotson commented Oct 17, 2022

In that case the problem is more about how the lib is loaded for Android than just the directory name.

The articles you provide describe native libs that are within the project, but not really about native libs that are within a dependency though.

@jrjohn
Copy link
Author

jrjohn commented Oct 17, 2022

So currently if i use

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.navigation:navigation-fragment:2.3.5'
    implementation 'androidx.navigation:navigation-ui:2.3.5'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'org.xerial:sqlite-jdbc:3.39.3.0'

image

I need to add jniLibs to myapp source:

app
____src
_____|- main
________|-  jniLibs
_______________|-   armeabi-v7a
___________________|-   libsqlitejdbc.so
_______________|-  arm64-v8a
____________________|-   libsqlitejdbc.so
_______________|- x86
____________________|-   libsqlitejdbc.so
_______________|- x86_64
____________________|-  libsqlitejdbc.so 

I think this should be included in the jar file.

@gotson
Copy link
Collaborator

gotson commented Oct 17, 2022

I was checking this in Android Studio, and i think the problem lies elsewhere.

When i opened the APK generated by Android Studio, i can see the Mac and Windows native libraries in /org/sqlite/native, but not the other libraries for Linux.

I have a feeling that they are excluded by Gradle automatically because they are .so.

@gotson
Copy link
Collaborator

gotson commented Oct 17, 2022

I couldn't fathom how the library loading worked, and i just found out that specific bit of code for Android.

When Android is detected, it uses System.loadLibrary instead of the SQLiteJDBCLoader.

My understanding is that

  • Gradle dependencies cannot have .so files in it. If they do, those are stripped in the resulting APK (as i found out in the previous comment).
  • System.loadLibrary will find the libraries without having to provide the full path, but that requires the libraries to be added to the jniLibs directory in Android Studio

I feel like this is not an issue, but should be properly documented.

There's no way the jar can provide the android libraries in the right folder AFAIK. If you can find a way for a third-party dependency to provide native libs for Android, we can evaluate a change.

@gotson
Copy link
Collaborator

gotson commented Oct 18, 2022

I also found this: https://developer.android.com/studio/releases/gradle-plugin#extractNativeLibs

I haven't found how to keep the .so files in the APK, but it seems it's not the best way to do for Android.

Ideally what we should have is a way to automatically:

  • extract the 4 android libraries from the jar during build
  • strip the other libraries of the jar in order to optimize the apk size

That would be however outside of the scope of this project, and should probably be handled by a dedicated Gradle plugin for Android.

@jrjohn
Copy link
Author

jrjohn commented Oct 18, 2022

I'll try how can finish read .so file from the jar file and report it here. Thanks

@gotson gotson closed this as completed in 7912b6b Oct 18, 2022
@github-actions github-actions bot added the released Issue has been released label Nov 7, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Nov 7, 2022

🎉 This issue has been resolved in 3.39.4.0 (Release Notes)

@SeregaYakovlev

This comment was marked as off-topic.

Repository owner locked as resolved and limited conversation to collaborators Dec 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
documentation released Issue has been released
Projects
None yet
Development

No branches or pull requests

3 participants