sqlcipher / sqlcipher-android

SQLCipher for Android provides an interface to SQLCipher databases on the Android platform.
Other
108 stars 19 forks source link

App getting crash #4

Open bharathkandula99 opened 2 years ago

bharathkandula99 commented 2 years ago

implementation 'net.zetetic:sqlcipher-android:4.5.2' implementation 'androidx.sqlite:sqlite:2.1.0'

Here are the logs I am getting,

java.lang.UnsatisfiedLinkError: No implementation found for long net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen and Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ) at net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(Native Method) at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:222) at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:198) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:474) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189) at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181) at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1029) at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1014) at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:841) at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:813) at net.zetetic.database.sqlcipher.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:910)

developernotes commented 2 years ago

Hi @bharathkandula99

Are you using abiFilters or ProGuard in your build? If so, can you temporarily disable that and try your example again? Would you also verify the native library presence by unpacking your APK using Apktool?

theBlbDan commented 1 year ago

@developernotes I finally made the move to sqlcipher-android from android-database-sqlcipher. I've been receiving crash reports from the wild on Nexus 5X devices. It looks similar to the one above. I do use ProGuard, but I don't have any feasible way to disable and test.

"PHONE_MODEL": "Nexus 5X",
    "BRAND": "google",
    "PRODUCT": "bullhead",
    "ANDROID_VERSION": "8.1.0",
    "BUILD":
    {
        "BOARD": "bullhead",
        "BOOTLOADER": "BHZ32c",
        "BRAND": "google",
        "CPU_ABI": "x86",
        "CPU_ABI2": "",
        "DEVICE": "bullhead",
        "DISPLAY": "OSM1.180201.031",
        "FINGERPRINT": "google\/bullhead\/bullhead:8.1.0\/OSM1.180201.031\/5455776:user\/release-keys",
        "HARDWARE": "batwing",
        "HOST": "xpce9.ams.corp.google.com",
        "ID": "OSM1.180201.031",
        "IS_CONTAINER": false,
        "IS_DEBUGGABLE": false,
        "IS_EMULATOR": true,
        "IS_ENG": false,
        "IS_TREBLE_ENABLED": true,
        "IS_USER": true,
        "IS_USERDEBUG": false,
        "MANUFACTURER": "LGE",
        "MODEL": "Nexus 5X",
        "PERMISSIONS_REVIEW_REQUIRED": false,
        "PRODUCT": "bullhead",
        "RADIO": "M8974A-2.0.50.2.22",
        "SUPPORTED_32_BIT_ABIS": ["x86"],
        "SUPPORTED_64_BIT_ABIS": [],
        "SUPPORTED_ABIS": ["x86"],
        "TAGS": "release-keys",
        "TIME": 1554922978000,
        "TYPE": "user",
        "UNKNOWN": "unknown",
        "USER": "android-build",
        "VERSION":
        {
            "ACTIVE_CODENAMES": [],
            "BASE_OS": "",
            "CODENAME": "REL",
            "INCREMENTAL": "5455776",
            "PREVIEW_SDK_INT": 0,
            "RELEASE": "8.1.0",
            "RESOURCES_SDK_INT": 27,
            "SDK": "27",
            "SDK_INT": 27,
            "SECURITY_PATCH": "2018-01-05"
        }
    }
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.blueletterbible.blb-fHiuvBvgQ2gHHaR32Zn6NA==/base.apk"],nativeLibraryDirectories=[/data/app/org.blueletterbible.blb-fHiuvBvgQ2gHHaR32Zn6NA==/lib/x86, /system/lib, /vendor/lib]]] couldn't find "libsqlcipher.so"
    at java.lang.Runtime.loadLibrary0(Runtime.java:1011)
    at java.lang.System.loadLibrary(System.java:1657)
    at org.blueletterbible.blb.MainAppLauncher.onCreate(jarjar:3)
    at android.app.Activity.performCreate(Activity.java:7009)
    at android.app.Activity.performCreate(Activity.java:7000)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
developernotes commented 1 year ago

Hi @theBlbDan,

A couple of questions regarding your application configuration:

We had a long thread in the android-database-sqlcipher project awhile back here regarding a similar issue where the usage of both the ReLinker library and SplitInstallHelper were suggested as possible solutions. Are you using either of those currently?

theBlbDan commented 1 year ago

I saw issue 587 last night and read through it as well as this one.

I do use App Bundles and no on abiFilters. My minSDK is 24, so ReLinker won't be of any use. I don't believe that SplitInstallHelper is of any use when using App Bundles.

Of the 400+ crash reports I've received on this new build, it's only affecting three devices and is definitely on first installs. I'm only at 25% roll-out, so that is helping to keep it reduced.

Possibly related? Native library failed to load

mandrachek commented 11 months ago

I'm seeing this intermittently as well in our release builds (proguarded). Our debug builds don't seem to suffer from this problem.

developernotes commented 10 months ago

Hi @theBlbDan,

I'm sorry for the delay in response, I didn't receive a notification to your latest reply. This may be a stretch, but I did find this reference on StackOverflow ^1 which could be related to your specific release packaging. Would you mind taking a look and let us know if this change impacts the behavior you are seeing? Thanks!

mandrachek commented 10 months ago

@developernotes - FWIW, I'm dealing with straight APKs, no app bundles. I'm seeing this in my minified release builds (with proguard rules added ala #18 , but my debug builds work fine. Stack trace is a little bit different since we're using Room (and 4.5.5, so line numbers are a little bit different), but fails at the same nativeOpen call.

Fatal Exception: java.lang.UnsatisfiedLinkError: No implementation found for long net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen and Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ)
   at net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(SQLiteConnection.java)
   at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:226)
   at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:202)
   at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:474)
   at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
   at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
   at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1028)
   at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java)
   at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:840)
   at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:359)
   at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:278)
   at net.zetetic.database.sqlcipher.SupportHelper.getWritableDatabase(SupportHelper.java:60)
   at androidx.room.RoomDatabase.inTransaction(RoomDatabase.kt:632)
   at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.kt)
   at androidx.room.RoomDatabase.query(RoomDatabase.kt:480)
   at androidx.room.util.DBUtil.query(DBUtil.java:75)
   at com.myapp.dao.AppStateDao_Impl$5.call(AppStateDao_Impl.java:124)
   at com.myapp.dao.AppStateDao_Impl$5.call(AppStateDao_Impl.java)
   at androidx.room.CoroutinesRoom$Companion$execute$4$job$1.invokeSuspend(CoroutinesRoom.kt:87)
   at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
   at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
   at java.lang.Thread.run(Thread.java:920)

We had to rollback to the 4.5.4 legacy library due to this issue.

developernotes commented 10 months ago

@mandrachek out of curiosity, do you have something like this within your ProGuard file:

-keepclasseswithmembernames class * {
    native <methods>;
}

If not, would you add it and let us know if the behavior is different with a release build?

mandrachek commented 10 months ago

Yes, that's already in our proguard-rules.pro

developernotes commented 10 months ago

@mandrachek if you disable ProGuard, but perform a release build does it still crash?

mandrachek commented 10 months ago

@developernotes - checking... yes, even with minification disabled, the release build crashes.

The only differences in configuration for us are pretty standard stuff - signing configurations, a couple manifest placeholders (release builds have canProfile set to true, debug builds have useCleartextTraffic set to true), and debug builds have isDebuggable set to true, and release builds (normally) have isMinifyEnabled (and proguard files set up)

mandrachek commented 10 months ago

@developernotes - I noticed that in the merged manifest, android:extractNativeLibs="false" is set on the <application/>. I tried adding android:extractNativeLibs="true" in my manifest, and the packaging.jniLibs.useLegacyPackaging=true in my build.gradle.kts. The release build no longer crashes!

According to the tooltip, if extractNativeLibs is false, the libraries have to be stored and page-aligned. Is it possible the libsqlcipher.so in the aar is not page-aligned?

mandrachek commented 10 months ago

Well... I spoke too soon turns out that didn't solve the problem. It appeared to delay it. I was able to launch our app, login, download data, put it in a sqlcipher db, and then at some point, down the road, while using the app, blammo:

FATAL EXCEPTION: DefaultDispatcher-worker-3
    Process: com.myapp, PID: 27195
    java.lang.UnsatisfiedLinkError: No implementation found for long net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen and Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ) - is the library loaded, e.g. System.loadLibrary?
        at net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(Native Method)
        at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:226)
        at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:202)
        at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:474)
        at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
        at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
        at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1028)
        at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1013)
        at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:840)
        at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:359)
        at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:278)
        at net.zetetic.database.sqlcipher.SupportHelper.getWritableDatabase(SupportHelper.java:60)
        at androidx.room.RoomDatabase.inTransaction(RoomDatabase.kt:632)
        at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.kt:451)
        at androidx.room.RoomDatabase.query(RoomDatabase.kt:480)
        at androidx.room.util.DBUtil.query(DBUtil.kt:75)
        at com.myapp.dao.AppStateDAO_Impl$5.call(AppStateDAO_Impl.java:124)
        at com.myapp.dao.AppStateDAO_Impl$5.call(AppStateDAO_Impl.java:120)
        at androidx.room.CoroutinesRoom$Companion$execute$4$job$1.invokeSuspend(CoroutinesRoom.kt:87)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
        at java.lang.Thread.run(Thread.java:1012)
        Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException:         [StandaloneCoroutine{Cancelling}@401291b, Dispatchers.IO]
mandrachek commented 10 months ago

@developernotes no luck.

mandrachek commented 9 months ago

Still haven't been able to figure this out. :(

goldfish07 commented 9 months ago

Still haven't been able to figure this out. :(

download that app from playstore , slideloads app gets this crashs only

developernotes commented 9 months ago

@goldfish07 are you using ProGuard?

theBlbDan commented 9 months ago

@developernotes For me, I had to disable R8, and I've reverted to using APK over bundles. It isn't the optimal solution, but the UnsatisfiedLinkError linker error has gone away.

I am currently chasing a java.lang.IllegalStateException: Cannot perform this operation because the connection pool has been closed. issue that I am unsure who is at fault.

zkrige commented 9 months ago

@theBlbDan #15 I migrated to sqlcipher recently and started seeing these crashes. I never had them when using plain slit

goldfish07 commented 9 months ago

@goldfish07 are you using ProGuard?

yes

developernotes commented 9 months ago

Hi @zkrige,

We recently merged in a pull request for ProGuard support within the library. Can you compare your configuration to this?

zkrige commented 9 months ago

thanks @developernotes - I dont think #15 is related to proguard as its not complaining about classes not found - its complaining about connection being closed when it shouldn't be. I was just letting @theBlbDan know that I had the same crash

developernotes commented 9 months ago

@mandrachek can you try out the new ProGuard configuration that was merged into master here. Additionally, if you're not already using zipalign on your APK, would you try with this usage, in particular the -p to ensure the 4k page alignment for the embedded .so files?

mandrachek commented 8 months ago

@developernotes -Sorry, but that doesn't help.

I'm doing ./gradlew assembleRelease, which already does the zipAlign, and my apk file verifies successfully. My app launches, but shortly thereafter:

java.lang.UnsatisfiedLinkError: No implementation found for long net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen and Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ)
    at net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(Native Method)
    at net.zetetic.database.sqlcipher.SQLiteConnection.open(SourceFile:5)
    at net.zetetic.database.sqlcipher.SQLiteConnection.open(SourceFile:2)
    at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(Unknown Source:6)
    at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SourceFile:4)
    at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SourceFile:2)
    at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(Unknown Source:5)
    at net.zetetic.database.sqlcipher.SQLiteDatabase.open(Unknown Source:0)
    at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SourceFile:7)
    at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(Unknown Source:131)
    at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getWritableDatabase(SourceFile:3)
    at net.zetetic.database.sqlcipher.SupportHelper.getWritableDatabase(Unknown Source:2)
    at androidx.room.h0.z(Unknown Source:4)
    at androidx.room.h0.d(Unknown Source:0)
    at androidx.room.h0.L(Unknown Source:8)
    at xc.a.n(Unknown Source:11)
    at com.myapp.dao.p$e.a(Unknown Source:9)
    at com.myapp.dao.p$e.call(Unknown Source:0)
    at androidx.room.i.invokeSuspend(Unknown Source:9)
    at uo.a.resumeWith(Unknown Source:7)
    at sr.k0.run(Unknown Source:113)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
    at java.lang.Thread.run(Thread.java:1012)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [v1{Cancelling}@de0002, Dispatchers.IO]

If you recall, I also get the crash on my release builds even with R8/Proguard disabled (isMinified = false).

java.lang.UnsatisfiedLinkError: No implementation found for long net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen and Java_net_zetetic_database_sqlcipher_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ)
    at net.zetetic.database.sqlcipher.SQLiteConnection.nativeOpen(Native Method)
    at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:226)
    at net.zetetic.database.sqlcipher.SQLiteConnection.open(SQLiteConnection.java:202)
    at net.zetetic.database.sqlcipher.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:474)
    at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
    at net.zetetic.database.sqlcipher.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
    at net.zetetic.database.sqlcipher.SQLiteDatabase.openInner(SQLiteDatabase.java:1028)
    at net.zetetic.database.sqlcipher.SQLiteDatabase.open(SQLiteDatabase.java:1013)
    at net.zetetic.database.sqlcipher.SQLiteDatabase.openDatabase(SQLiteDatabase.java:840)
    at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:359)
    at net.zetetic.database.sqlcipher.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:278)
    at net.zetetic.database.sqlcipher.SupportHelper.getWritableDatabase(SupportHelper.java:60)
    at androidx.room.RoomDatabase.inTransaction(RoomDatabase.kt:632)
    at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.kt:451)
    at androidx.room.RoomDatabase.query(RoomDatabase.kt:480)
    at androidx.room.util.DBUtil.query(DBUtil.kt:75)
    at com.myapp.dao.AppStateDAO_Impl$5.call(AppStateDAO_Impl.java:124)
    at com.myapp.dao.AppStateDAO_Impl$5.call(AppStateDAO_Impl.java:120)
    at androidx.room.CoroutinesRoom$Companion$execute$4$job$1.invokeSuspend(CoroutinesRoom.kt:87)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
    at java.lang.Thread.run(Thread.java:1012)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@b26d347, Dispatchers.IO]

I'm doing:

 override fun onCreate() {
        super<Application>.onCreate()
        System.loadLibrary("sqlcipher");
        ...
}

It's like some of the room/coroutine threads can't see the loaded library.

mandrachek commented 8 months ago

So, I think I've got a fix! Loading the native library in onCreate() doesn't appear to be sufficient.

We have a number of database modules that look something like this:

@Module
@InstallIn(SingletonComponent::class)
object MyDatabaseModule {
    @Singleton
    @Provides
    fun provideMyDatabase(
        @ApplicationContext context: Context,
        ...
    ): MyDatabase = Room.databaseBuilder(
        context,
        MyDatabase::class.java,
       MY_DATABASE
    )
        .setJournalMode(RoomDatabase.JournalMode.WRITE_AHEAD_LOGGING)
        .fallbackToDestructiveMigration()
        .apply {            
                openHelperFactory(SupportOpenHelperFactory(password.toByteArray()))
}.build()

It looks like adding System.loadLibrary("sqlcipher") just above the openHelperFactory call resolves the issue. Trying in a minified build to double check. I'm guessing this is something the SupportFactory used to do for us.

mandrachek commented 8 months ago

@developernotes ^^ - this was indeed the fix for me.

developernotes commented 8 months ago

Hello @mandrachek,

Thank you for your follow-up, we're happy to hear you were able to resolve the issue. Loading the native library into the running process is required before initializing any SQLCipher Java component (i.e., SQLiteDatabase, SQLiteOpenHelper, or SupportOpenHelperFactory).

mandrachek commented 8 months ago

@developernotes - the odd thing is that it's called in my application.onCreate() - I must have one being injected by dagger/hilt before the onCreate() call.

Damercy commented 6 months ago

@mandrachek's solution also worked for me, thanks! Here's what seems to be working (as said earlier @mandrachek ):

    @Singleton
    @Provides
    fun provideAppDatabase(@ApplicationContext context: Context): DB =
        Room.databaseBuilder(
            context.applicationContext,
            DB::class.java,
            Constants.DB_NAME
        )
            .apply {
                // 1. Load library here.
                System.loadLibrary("sqlcipher")
               // 2. Enable WAL journal mode to improve performance as per official doc.
                openHelperFactory(SupportOpenHelperFactory(Keys.secretKeyForEncryption().toByteArray(),null,true))
            }
            .fallbackToDestructiveMigration()
            .build()

Do enable WAL journal mode to improve performance as per the official doc.

adewan101 commented 1 month ago

We are running into a similar issue and based on what I can see calling System.loadLibrary("sqlcipher") right before getting a writeable database doesn't seem to always fix this issue. In one app, doing that still results in this error where as in another app I can add this and it fixes it for that.

Is there a a threading components as in on whatever thread isn't being called? Basing this on https://github.com/sqlcipher/sqlcipher-android/issues/4#issuecomment-1838974438 where it's mentioned that it seems like the coroutines aren't aware of the library being loaded?

Any other potential reasons that I could look into. I tried the proguard but with or without it (in debug builds) I'm seeing this issue.