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

App getting crash #4

Open
bharathkandula99 opened this issue Aug 24, 2022 · 30 comments
Open

App getting crash #4

bharathkandula99 opened this issue Aug 24, 2022 · 30 comments

Comments

@bharathkandula99
Copy link

  • Added a below line of code in my code base
    SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbOutputFile, "password", null, null, null);

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 developernotes transferred this issue from sqlcipher/android-database-sqlcipher Aug 24, 2022
@developernotes
Copy link
Member

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
Copy link

@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
Copy link
Member

developernotes commented Aug 4, 2023

Hi @theBlbDan,

A couple of questions regarding your application configuration:

  • Are you abiFilters within your build configuration?
  • Do you deploy your application using Android App Bundles?

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
Copy link

theBlbDan commented Aug 4, 2023

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
Copy link

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

@developernotes
Copy link
Member

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!

Footnotes

  1. https://stackoverflow.com/questions/62807988/android-app-bundle-only-native-library-failed-to-load

@mandrachek
Copy link

@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
Copy link
Member

@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
Copy link

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

@developernotes
Copy link
Member

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

@mandrachek
Copy link

@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
Copy link

mandrachek commented Oct 5, 2023

@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
Copy link

mandrachek commented Oct 6, 2023

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
Copy link

@developernotes no luck.

@mandrachek
Copy link

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

@goldfish07
Copy link

goldfish07 commented Nov 20, 2023

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

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

@developernotes
Copy link
Member

@goldfish07 are you using ProGuard?

@theBlbDan
Copy link

@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
Copy link

zkrige commented Nov 21, 2023

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

@goldfish07
Copy link

@goldfish07 are you using ProGuard?

yes

@developernotes
Copy link
Member

Hi @zkrige,

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

@zkrige
Copy link

zkrige commented Nov 22, 2023

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
Copy link
Member

@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
Copy link

@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
Copy link

mandrachek commented Dec 4, 2023

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
Copy link

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

@developernotes
Copy link
Member

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
Copy link

@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
Copy link

Damercy commented Feb 18, 2024

@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
Copy link

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 #4 (comment) 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants