sqlite-jdbc icon indicating copy to clipboard operation
sqlite-jdbc copied to clipboard

Android UnsatisfiedLinkError

Open spyhunter99 opened this issue 7 years ago • 16 comments

Device: samsung s5 with android 6.0.0, api23, with permissions granted

Here's the dependency parts of the gradle build file


dependencies {

    compile 'com.android.support:support-v4:23+'
    compile 'com.android.support:design:23.+' //needed for UI menuing
    compile 'com.android.support:appcompat-v7:23.2.1'
    compile 'org.xerial:sqlite-jdbc:3.20.0'
    compile 'commons-io:commons-io:2.5'
    compile 'org.apache.commons:commons-lang3:3.6'
    compile 'org.apache.commons:commons-compress:1.11'
    testCompile 'junit:junit:4.12'
    //crash logging
    compile 'ch.acra:acra:4.7.0'

    //memory leak testing
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
    testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'

    //on device testing
    androidTestCompile 'com.android.support:support-annotations:23+'
    androidTestCompile 'com.android.support.test:runner:0.4.+'
    androidTestCompile 'com.android.support.test:rules:0.4.+'
}

Other build settings

android-plugin.version=2.1.0
android-support.version=23.1.1
android.buildToolsVersion=23.0.3
android.compileSdkVersion=23
android.minSdkVersion=8
android.targetSdkVersion=23

Initialization code

 DriverManager.registerDriver((Driver) Class.forName(
                             "org.sqlite.JDBC").newInstance());
                    Connection con = DriverManager.getConnection("jdbc:sqlite:/sdcard/importTest.sqlite");

Error message

E/AndroidRuntime: FATAL EXCEPTION: Thread-23816
                                                                             Process: org.osmdroid.reader.example, PID: 10352
                                                                             java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.osmdroid.reader.example-2/base.apk"],nativeLibraryDirectories=[/data/app/org.osmdroid.reader.example-2/lib/arm, /vendor/lib, /system/lib]]] couldn't find "libsqlitejdbc.so"
                                                                                 at java.lang.Runtime.loadLibrary(Runtime.java:367)
                                                                                 at java.lang.System.loadLibrary(System.java:1076)
                                                                                 at org.sqlite.core.NativeDB.<clinit>(NativeDB.java:38)
                                                                                 at org.sqlite.core.CoreConnection.open(CoreConnection.java:211)
                                                                                 at org.sqlite.core.CoreConnection.<init>(CoreConnection.java:76)
                                                                                 at org.sqlite.jdbc3.JDBC3Connection.<init>(JDBC3Connection.java:26)
                                                                                 at org.sqlite.jdbc4.JDBC4Connection.<init>(JDBC4Connection.java:24)
                                                                                 at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:45)
                                                                                 at org.sqlite.JDBC.createConnection(JDBC.java:114)
                                                                                 at org.sqlite.JDBC.connect(JDBC.java:88)
                                                                                 at java.sql.DriverManager.getConnection(DriverManager.java:179)
                                                                                 at java.sql.DriverManager.getConnection(DriverManager.java:144)
                                                                                 at org.osmdroid.reader.MainActivity$2.run(MainActivity.java:86)

At this point, i'm not too sure what i'm doing wrong.

spyhunter99 avatar Aug 12 '17 21:08 spyhunter99

org.sqlite.util.OSInfo.isAndroid() resolves to true btw

spyhunter99 avatar Aug 12 '17 21:08 spyhunter99

i suspect that android looks for native binaries in a strange and different location than normal in apk's. After extracting them from the xerial jar and placing them in the right location, i was able to get sqlite to fire up on arm devices using the androidarm binary. Android x86 however fails with a message related to missing libc (this was when attempting to use the linux intel x86 binary on android x86). So if you all could add that to a future version, that would be great!

I'm using genymotion as a test bed if you need to reproduce

spyhunter99 avatar Aug 14 '17 00:08 spyhunter99

@spyhunter99 Could you tell me which native library file you used? I'd like to fix the build script to place it to a proper location.

xerial avatar Aug 14 '17 16:08 xerial

If I understood correctly - it became possible (?) now to use this driver in android applications.

2017-01-10: sqlite-jdbc-3.16.1 -Add experimental support for ppc64, armv5, v6 (Raspberry PI), v7 and android-arm.

But it's impossible to get connection in 3.20.0 (from maven dependency):

java.lang.UnsatisfiedLinkError: Couldn't load sqlitejdbc from loader dalvik.system.PathClassLoader[dexPath=/data/app/com.caveman.myapplication-1.apk,libraryPath=/data/app-lib/com.caveman.myapplication-1]: findLibrary returned null
                                                       at java.lang.Runtime.loadLibrary(Runtime.java:365)
                                                       at java.lang.System.loadLibrary(System.java:535)
                                                       at org.sqlite.core.NativeDB.<clinit>(NativeDB.java:38)
                                                       at org.sqlite.core.CoreConnection.open(CoreConnection.java:211) 
                                                       at org.sqlite.core.CoreConnection.<init>(CoreConnection.java:76) 
                                                       at org.sqlite.jdbc3.JDBC3Connection.<init>(JDBC3Connection.java:26) 
                                                       at org.sqlite.jdbc4.JDBC4Connection.<init>(JDBC4Connection.java:24) 
                                                       at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:45) 
                                                       at org.sqlite.JDBC.createConnection(JDBC.java:114) 
                                                       at org.sqlite.JDBC.connect(JDBC.java:88) 
                                                       at java.sql.DriverManager.getConnection(DriverManager.java:175) 
                                                       at java.sql.DriverManager.getConnection(DriverManager.java:140) 

Regardless of how the driver is loaded: DriverManager.registerDriver((Driver) Class.forName("org.sqlite.JDBC").newInstance()); or Class.forName("org.sqlite.JDBC");

an error occurs on the: Connection connection = DriverManager.getConnection("jdbc:sqlite:" + ...)

NudeCaveMan avatar Aug 18 '17 01:08 NudeCaveMan

@xerial the android arm library. I basically copied this from within th embedded xerial jar file into the apkmodule/src/main/jnilibs/armeabi/libsqlitejdbc.so. Here's the project actually. https://github.com/spyhunter99/osmreader/tree/master/OsmReaderExampleApp

it seems as if android will only allow native libs from loading when they are in that particular directory. I'm not too sure if there's anything you all can do besides document how to do this.

spyhunter99 avatar Aug 18 '17 01:08 spyhunter99

@NudeCaveMan pretty much. if the native libs can't be loaded no connection can't be made

spyhunter99 avatar Aug 18 '17 01:08 spyhunter99

Hi @xerial I'm having a similar issue when using sqlite-jdbc-3.20.0.jar as a library for an Android Studio project build. The app runs in a armv7l and throws the java.lang.UnsatisfiedLinkError [...] couldn't find "libsqlitejdbc.so". Moreover, the search path seems to be [...] nativeLibraryDirectories=[{1}, /vendor/lib, /system/lib].

Additionally, the same library (code) runs (test) in Linux amd64 and Java 1.7 without a single issue.

{1} Application's specific native (os architecture dependent) library directory. (e.g., "/data/app/org.xerial.sqlite-jdbc/lib/arm"). Android API string with the path: getApplicationContext().getApplicationInfo().nativeLibraryDir.

nunoachenriques avatar Sep 05 '17 13:09 nunoachenriques

I am having the same issue with compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.20.1'

E/AndroidRuntime: FATAL EXCEPTION: Thread-289 Process: PID: 6186 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file [...],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libsqlitejdbc.so" at java.lang.Runtime.loadLibrary(Runtime.java:366) Did I understand it correctly, that a workaround is to create a folder app/src/main/jnilibs/armeabi/

and place the libsqlitejdbc.so from sqlite-jdbc-3.20.1.jar!\org\sqlite\native\Linux\armv7\libsqlitejdbc.so in it?

michi-k avatar Nov 03 '17 18:11 michi-k

I think OSInfo needs to be fixed to use the android native library: https://github.com/xerial/sqlite-jdbc/blob/master/src/main/java/org/sqlite/util/OSInfo.java#L145

xerial avatar Dec 01 '17 00:12 xerial

@NudeCaveMan Im having same issue, did you find a solution for this ?

VinsoyTisoy avatar Nov 28 '18 01:11 VinsoyTisoy

I ended up not using xerial for Android - why anyway? If you want to store data on the device, you use SQLDroid and for storing in other databases in 99,9% you probably don't work with direct connections from the device to the database. With SQLDroid you can do it the jdbc way but when getting connection in try-with-resource blocks your connection gets closed when leaving the block, thats a thing you don't want with SQLite on Android. I solved this by overriding the close() of SQLDroidConnection with an empty implementation. For Java, xerial is great when you want to use SQLite the jdbc way!

michi-k avatar Nov 28 '18 07:11 michi-k

@xerial any update for the android x86 binary?

dev-ritik avatar May 16 '19 18:05 dev-ritik

I am having the same issue with compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.25.2'

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file [...],nativeLibraryDirectories=[/vendor/lib64, /system/lib64, /storage/emulated/0/jetty/lib]]] couldn't find "libsqlitejdbc.so" at java.lang.Runtime.loadLibrary(Runtime.java:366)

This exception occurred at NativeDB.java

    static {
        if ("The Android Project".equals(System.getProperty("java.vm.vendor"))) {
            System.loadLibrary("sqlitejdbc");
            isLoaded = true;
            loadSucceeded = true;
        } else {
            // continue with non Android execution path
            isLoaded = false;
            loadSucceeded = false;
        }
        isLoaded = false;
        loadSucceeded = false;
    }

first, I add a custom nativeLibraryDirectory, and copy the "libsqlitejdbc.so" to that directory, the same error.

then I comment out the following code:

    static {
//        if ("The Android Project".equals(System.getProperty("java.vm.vendor"))) {
//            System.loadLibrary("sqlitejdbc");
//            isLoaded = true;
//            loadSucceeded = true;
//        } else {
//            // continue with non Android execution path
//            isLoaded = false;
//            loadSucceeded = false;
//        }
        isLoaded = false;
        loadSucceeded = false;
    }

and set the property:

System.setProperty("org.sqlite.lib.path", "/storage/emulated/0/jetty/lib");
System.setProperty("org.sqlite.lib.name", "libsqlitejdbc.so");

Solved this problem.

But I don't know why System.loadLibrary("sqlitejdbc") can't find the so file, I already add the custom nativeLibraryDirectory to the dalvik.system.PathClassLoader. Can anyone tell me?

zollty avatar May 25 '19 09:05 zollty

I'm trying to use the Xerial jdbc driver in a Flutter app. The first time I run it, I got the couldn't find "libsqlitejdbc.so" error. Then, following @spyhunter99 workaround (extracting the native libs inside the Xerial-sqlite-jdbc .jar into the <my-flutter-proj-root>/android/app/src/main/jniLibs folder. Now I get a couldn't find "libc.so.6" error.

Don't anyone get any workaround this?

The stack trace of the error is:

E/flutter ( 8946): [ERROR:flutter/shell/platform/android/platform_view_android_jni.cc(39)] java.lang.UnsatisfiedLinkError: dlopen failed: library "libc.so.6" not found
                    E/flutter ( 8946):      at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
                    E/flutter ( 8946):      at java.lang.System.loadLibrary(System.java:1669)
                    E/flutter ( 8946):      at org.sqlite.core.NativeDB.(NativeDB.java:39)
                    E/flutter ( 8946):      at org.sqlite.core.NativeDB.load(NativeDB.java:60)
                    E/flutter ( 8946):      at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:235)
                    E/flutter ( 8946):      at org.sqlite.SQLiteConnection.(SQLiteConnection.java:61)
                    E/flutter ( 8946):      at org.sqlite.jdbc3.JDBC3Connection.(JDBC3Connection.java:28)
                    E/flutter ( 8946):      at org.sqlite.jdbc4.JDBC4Connection.(JDBC4Connection.java:21)
                    E/flutter ( 8946):      at org.sqlite.JDBC.createConnection(JDBC.java:115)
                    E/flutter ( 8946):      at org.sqlite.SQLiteDataSource.getConnection(SQLiteDataSource.java:410)
                    E/flutter ( 8946):      at org.sqlite.SQLiteDataSource.getConnection(SQLiteDataSource.java:398)
                    E/flutter ( 8946):      at com.example.marmota.MainActivity.createDatasource(MainActivity.java:63)
                    E/flutter ( 8946):      at com.example.marmota.MainActivity.lambda$onCreate$0(MainActivity.java:31)
                    E/flutter ( 8946):      at com.example.marmota.-$$Lambda$MainActivity$a5KG7mF0KB TpR-KNWNL6uxSTCZo.onMethodCall(Unknown Source:2)
                    E/flutter ( 8946):      at io.flutter.plugin.common.MethodChannel$IncomingMethod CallHandler.onMessage(MethodChannel.java:222)
                    E/flutter ( 8946):      at io.flutter.embedding.engine.dart.DartMessenger.handle MessageFromDart(DartMessenger.java:96)

Also, if there is some missing information about the project that is relevant for any workaround, please let me know. I'm new with Android development and also with Flutter development. I have no solid ground to tell what is relevant and what is not.

jeffque avatar Jul 31 '19 18:07 jeffque

Any update on .so file for x86? If load the lib.so file gets below error?

java.lang.UnsatisfiedLinkError: dlopen failed: library "libc.so.7" not found at java.lang.Runtime.loadLibrary(Runtime.java:372) at java.lang.System.loadLibrary(System.java:1076)

vkhooda24 avatar Nov 17 '19 00:11 vkhooda24

Is this still happening on the latest version?

gotson avatar Jul 29 '22 05:07 gotson

Closing this as we now have all supported architectures for Android.

gotson avatar Sep 20 '22 03:09 gotson

Still same issue current status on android

implementation 'org.xerial:sqlite-jdbc:3.39.3.0'

2022-10-12 17:51:04.196 27896-27896/com.demo.sqlite E/AndroidRuntime: FATAL EXCEPTION: main Process: com.demo.sqlite, PID: 27896 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.demo.sqlite-Ku3Nl4WVK03vQjGQ2FqkaA==/base.apk"],nativeLibraryDirectories=[/data/app/com.demo.sqlite-Ku3Nl4WVK03vQjGQ2FqkaA==/lib/arm64, /system/lib64, /system/vendor/lib64]]] couldn't find "libsqlitejdbc.so" at java.lang.Runtime.loadLibrary0(Runtime.java:1012) at java.lang.System.loadLibrary(System.java:1669) at org.sqlite.core.NativeDB.(NativeDB.java:40) at org.sqlite.core.NativeDB.load(NativeDB.java:60) at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:278) at org.sqlite.SQLiteConnection.(SQLiteConnection.java:65) at org.sqlite.jdbc3.JDBC3Connection.(JDBC3Connection.java:28) at org.sqlite.jdbc4.JDBC4Connection.(JDBC4Connection.java:19) at org.sqlite.JDBC.createConnection(JDBC.java:104)

jrjohn avatar Oct 12 '22 10:10 jrjohn