Wish SQLCipher 4.5.4 update

epiCode

Active Member
Licensed User
I needed FTS5 which is available in SQLCipher 4.5.4.
I tried compiling myself using SLC on code from github. Did not succeed due to many a.lang.NoClassDefFoundError. (Strangely it has package name anyhwheresoftware.b4a.objects.sqlcipher; with extra h after any)

Requesting @Erel for an update for this extremely useful library.
 

OliverA

Expert
Licensed User
Longtime User
I needed FTS5 which is available in SQLCipher 4.5.4.

I recommended SQLCiper back in 2019 for FTS5 support, and according to @jcmartini, it seemed to do the trick back then, with SQLCipher library v1.60 supporting "only" version 4.00.
 

epiCode

Active Member
Licensed User
Have you tried to simply change the dependency in the XML file?
Yes. 🤦‍♂️ It did not work.
Then I downloaded the SQLCipher.java, and modified dependency in code (also downloaded new .aar files), and tried compiling using SLC and failed.
 

epiCode

Active Member
Licensed User
You don't need to compile anything. Just change the dependecy.
Just changing the dependancy leads to this error on sqldb.initialize method.
B4X:
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/sqlite/db/SupportSQLiteDatabase;
PS: I ran jetifier too
 

Mahares

Expert
Licensed User
Longtime User
I needed FTS5 which is available in SQLCipher 4.5.4.
I have an FTS5 application that I run which uses Erel's SQL Cipher 1.60 and the sqlcipher-4.0.0 release. I did not have to upgrade to 4.5.4. If you want to attach a small and a simple project of your own using FTS5 where it did not work for you, I can try to test it on my end to see if it crashes the same way it did for you.
CREATE VIRTUAL TABLE IF NOT EXISTS ${DBTableName} USING fts5(........................
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Just changing the dependancy leads to this error on sqldb.initialize method.
B4X:
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/sqlite/db/SupportSQLiteDatabase;
PS: I ran jetifier too
Did you manage to fix this or did you just stick with the old SQLCipher?
I encountered similar problems trying to update to SQLCipher 4.5.6.

RBS
 

epiCode

Active Member
Licensed User
Did you manage to fix this or did you just stick with the old SQLCipher?
I encountered similar problems trying to update to SQLCipher 4.5.6.

RBS
Sticking to old version until Erel decides to realease a new version. Tried to compile myself but gave up after multiple issues encountered during compilation, which I could not navigate due to my lack of experience with java.
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Sticking to old version until Erel decides to realease a new version. Tried to compile myself but gave up after multiple issues encountered during compilation, which I could not navigate due to my lack of experience with java.
OK, I will do the same.
There is a newer version uploaded by Tummosoft in the libraries group, but it doesn't seem that is ready yet to be used in a complex app.

RBS
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
BTW, this error was misleading: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/sqlite/db/SupportSQLiteDatabase;
The class is there inside the AAR. The actual missing class comes from a different SDK. You can see the other dependency here: https://mvnrepository.com/artifact/net.zetetic/android-database-sqlcipher/4.5.4:

1709473077891.png
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Have downloaded android-database-sqlcipher-4.5.4.aar, sqlite-2.2.0.aar and also sqlite-2.4.0.aar (not sure which one of these last 2 were needed)
and put them in the additional library folder, altered the last few lines of SQLCipher.xml (the old 1.6 file):

<version>1.7</version>
<comment></comment>
<dependsOn>android-database-sqlcipher-4.5.4.aar</dependsOn>
</root>

Did a Jetify, but still get this run-time error.

Still getting this error:
java.lang.NoClassDefFoundError: Failed resolution of: Lnet/sqlcipher/database/SQLiteDatabase;
at anyhwheresoftware.b4a.objects.sqlcipher.SQLCipher.Initialize(SQLCipher.java:51)
at b4a.exampleljjll.clsconnection$ResumableSub_Connect2DB.resume(clsconnection.java:696)
at b4a.exampleljjll.clsconnection._connect2db(clsconnection.java:533)
at b4a.exampleljjll.b4xmainpage$ResumableSub_SetConnection.resume(b4xmainpage.java:40226)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:215)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.keywords.Common$15.run(Common.java:1804)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8893)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.ClassNotFoundException: net.sqlcipher.database.SQLiteDatabase
... 16 more

What else do I need to do or what do I need to do differently?

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Have downloaded android-database-sqlcipher-4.5.4.aar, sqlite-2.2.0.aar and also sqlite-2.4.0.aar (not sure which one of these last 2 were needed)
and put them in the additional library folder, altered the last few lines of SQLCipher.xml (the old 1.6 file):

<version>1.7</version>
<comment></comment>
<dependsOn>android-database-sqlcipher-4.5.4.aar</dependsOn>
</root>

Did a Jetify, but still get this run-time error.

Still getting this error:
java.lang.NoClassDefFoundError: Failed resolution of: Lnet/sqlcipher/database/SQLiteDatabase;
at anyhwheresoftware.b4a.objects.sqlcipher.SQLCipher.Initialize(SQLCipher.java:51)
at b4a.exampleljjll.clsconnection$ResumableSub_Connect2DB.resume(clsconnection.java:696)
at b4a.exampleljjll.clsconnection._connect2db(clsconnection.java:533)
at b4a.exampleljjll.b4xmainpage$ResumableSub_SetConnection.resume(b4xmainpage.java:40226)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:215)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.keywords.Common$15.run(Common.java:1804)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8893)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.ClassNotFoundException: net.sqlcipher.database.SQLiteDatabase
... 16 more

What else do I need to do or what do I need to do differently?

RBS
Solved this now by adding to B4XMainPage:

B4X:
#AdditionalJar: sqlite-2.4.0.aar
#AdditionalJar: android-database-sqlcipher-4.5.4.aar

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
BTW, this error was misleading: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/sqlite/db/SupportSQLiteDatabase;
The class is there inside the AAR. The actual missing class comes from a different SDK. You can see the other dependency here: https://mvnrepository.com/artifact/net.zetetic/android-database-sqlcipher/4.5.4:

View attachment 151416
I noticed SQLCipher 4.5.6 doesn't show up in the list at:
So, I guess there is no point in trying to update further to use sqlcipher-android-4.5.6.aar.

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Just fixed a bug in my app to do with updating SQLCipher from 1.6 to 1.7.
I have a complex Sub that replaces the vacuum command as I can't make this to work on large databases.
Part of that Sub is this Sub:

B4X:
Sub ExportDBToAttachedDB(tFF_A As tFolderAndFile, _
                         strAttachedDBName As String, _
                         strKeySourceDB As String, _
                         strKeyTargetDB As String) As ResumableSub
    
    Dim oRS As ResultSet 'ignore
    
    If strKeySourceDB.Length > 0 Then
    '-----------------------------------------------------------------------------------------------------------------
        'this used to be cConn.ExecNonQuery("PRAGMA key = '" & strKey & "'") with the old SQLCipher version
        'but that gives an error with the newer SQLCipher version 1.7 saying that in needs to be ExecQuery
        '-----------------------------------------------------------------------------------------------------------------
        cConn.ExecQuery("PRAGMA key = '" & strKeySourceDB & "'")
    End If
    
    cConn.AttachDB(tFF_A.strFolder & "/" & tFF_A.strFile, strAttachedDBName, strKeyTargetDB)
    
    'oRS will be a 1 row, 1 column ResultSet holding a Null (this is if the export was successful)
    oRS = cConn.ExecQuery("SELECT sqlcipher_export('" & strAttachedDBName & "')")
    
    '------------------------------------------------------------------------------------------------------------
    'without these 3 lines there will be an error due to a missing table in NON_CLINICAL.db if that was compacted
    'running instead a Sleep(10) doesn't solve this problem!
    '------------------------------------------------------------------------------------------------------------
    oRS.Position = 0
    Log(oRS.RowCount)
    Log(oRS.GetString2(0))
    
    Return True
    
End Sub

I suppose because PRAGMA key produces a result it always was meant to be run with ExecQuery, but for some reason with the old SQLCipher 1.6
running it with ExecNonQuery was fine.

RBS
 
Top