Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

"QSqlDatabase: QSQLITE driver not loaded" error in deploying a Qt-Android project using JNI with Android studio



  • I have a simple project in Qt (as dbManagement) which it tries to open Sqlite database in Android device. I have put my Sqlite database in /mnt/sdcard/.

    1-Every thing is OK when I build and deploy my project from Qt to my Android device.

    main.cpp

    #include <QApplication>
    #include "initialization.h"
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Initialization* initialization=new Initialization;
        initialization->checkSqlite();
        return a.exec();
    }
    

    initialization.cpp

    ...
    void Initialization::checkSqlite()
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE","SQLITE");
        db.setDatabaseName("/mnt/sdcard/database");
        if( !db.open() )
        {
            if(QFile("/mnt/sdcard/database").exists())
                LOGE("Checking database has error: database exists but %s.",db.lastError().driverText().toStdString().c_str());
            else
                LOGE("Checking database has error: database not exists.");
        }
        else
        {
            LOGE("Checking database is OK.");
        }
    }
    ...
    

    output:

    Checking database is OK.
    

    2- Now, I want to run an Android project using the created lib of my Qt project (libdbManagement.so) and JNI.

    Here is My CMakeLists.txt

    cmake_minimum_required(VERSION 3.4.1)
    include_directories(includes
            includes/QtCore
            includes/QtSql
            )
    link_directories(libs)
    add_library(polaris-lib SHARED main.cpp)
    target_link_libraries(
            polaris-lib
            -lQt5Sql
            -lQt5Core
            -llog
            -lz
            -ldbManagement
            -lQt5Network
    )
    

    And here is my main.cpp in my Android studio project using JNI:

    #include <jni.h>
    #include "initialization.h"
    #include <android/log.h>
    #define  LOG_TAG    "polaris-lib"
    #define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
    using namespace std;
    extern "C" JNIEXPORT void JNICALL
    Java_com_horizon_polarislib_MainActivity_startDiagBackgroundService(JNIEnv *env, jclass clazz) {
        Initialization* initialization=new Initialization;
        initialization->checkSqlite();
        LOGE("STARTED");
    }
    

    After building and running this Android project on my Android device, the output is:

    Checking database has error: database exists but Driver not loaded
    

    and I see these logs in Android Studio Run outputs:

    QSqlDatabase: QSQLITE driver not loaded
    QSqlDatabase: available drivers: 
    

    It seems that the libqsqlite.so is known in State 1 and is unknown in State 2. After googling this error, I can find some similar questions like this which suggests to put the libqsqlite.so into PARENT_FOLDER/sqldrivers/ and add PARENT_FOLDER to library path usingQCoreApplication::addLibraryPath. So, I have created a directory (/mnt/sdcard/plugins/sqldrivers) and put libqsqlite.so inside that. Also, I have added these codes to my Initialization::checkSqlite:

    QCoreApplication::addLibraryPath("/mnt/sdcard/plugins");
    QApplication::addLibraryPath("/mnt/sdcard/plugins");
    QStringList paths = QCoreApplication::libraryPaths();
    for (int i = 0; i < paths.count(); i++) {
        QString str=paths.at(i);
        LOGE("Path: %s",str.toStdString().c_str());
    }
    

    and I can see the Path: /mnt/sdcard/plugins in the above loop. But still the Sqlite driver is not loaded. Also, set the variable qputenv("QT_DEBUG_PLUGINS", QByteArray("1")) which is suggested in some links not works. What is the solution?


  • Qt Champions 2019

    The path is wrong - see https://doc.qt.io/qt-5/deployment-plugins.html
    Also make sure that the dependencies to libsqsqlite.so (I would quess libsqlite.so) is available.



  • @Christian-Ehrlicher Thanks, but it is said in the link which you mentioned,
    " If you want Qt to look in additional places you can add as many paths as you need with calls to QCoreApplication::addLibraryPath()."
    And I add my path using QCoreApplication::addLibraryPath().". Why this is wrong?


  • Qt Champions 2019

    @morteza-ali-ahmadi said in "QSqlDatabase: QSQLITE driver not loaded" error in deploying a Qt-Android project using JNI with Android studio:

    Why this is wrong?

    Because you don't need it when you use the correct location in the first place. It just make it more complicated than it really is and confuses others when reading your post (as you're already confused about while searching the net)
    And, as already said, make sure you also have the needed dependencies for the plugin available.



  • @Christian-Ehrlicher Thanks, Ok.
    As mentioned in this For checking dependency of libqslite.so, I run these commands, is this right?

        QLibrary lib("libqsqlite.so");
        if (! lib.load()) {
          qDebug() << "Library load error:" << lib.errorString();
        }
    
        QPluginLoader lib2("libqsqlite.so");
        if (! lib2.load()) {
          qDebug() << "Library load error:" << lib2.errorString();
        }
    

  • Qt Champions 2019

    I would run 'ldd' on the shell if there is any but yes, basically you can try to load them with QLibrary and see what the error is (if there is any)



  • @Christian-Ehrlicher After running ldd, this error appears:

    not a dynamic executable
    

    Using QLibrary, show this error:

        Trying... "/storage/emulated/0/plugins/libqsqlite.so"
        Trying... "/storage/emulated/0/plugins/libqsqlite.so.so"
        Trying... "/storage/emulated/0/plugins/liblibqsqlite.so"
        Trying... "/storage/emulated/0/plugins/liblibqsqlite.so.so"
        "libqsqlite.so" not found
        Library load error: "The shared library was not found."
    

    Don't forget I build and deploy this application using android studio on my Android device.
    It seems that the library path can not be identified. I am confused. How can I load that?


  • Qt Champions 2019

    @morteza-ali-ahmadi said in "QSqlDatabase: QSQLITE driver not loaded" error in deploying a Qt-Android project using JNI with Android studio:

    After running ldd, this error appears:

    This is what I expected - 'I would run 'ldd' on the shell if there is any' - you can't run ldd on the target so running it on the build system will not help at all.

    I would take a look with QFile/QFileInfo to see where the library is.



  • @Christian-Ehrlicher Finally in loading libqsqlite.so, this error appears:

    library "/storage/emulated/0/plugins/sqldrivers/libqsqlite.so" ("/storage/emulated/0/plugins/sqldrivers/libqsqlite.so") needed or dlopened by "/data/app/com.horizon.polarislib-1/lib/arm64/libQt5Core.so" is not accessible for the namespace: [name="classloader-namespace", ld_library_paths="", default_library_paths="/data/app/com.horizon.polarislib-1/lib/arm64:/data/app/com.horizon.polarislib-1/base.apk!/lib/arm64-v8a", permitted_paths="/data:/mnt/expand:/data/data/com.horizon.polarislib"]
    

    Can this error help?


  • Lifetime Qt Champion

    Hi,

    You can't put plugins anywhere you'd like. Qt follows a well defined structure and will search plugins in specific paths. You have to put the database related plugins under "plugins/sqldrivers".

    Edit: while the plugins have specific subfolders, it seems deployment have them in different places. See here



  • @SGaist Thanks, yes of course. I have put my libqsqlit.so in /mnt/sdcard/plugins/sqldrivers/ and added /mnt/sdcard/plugins/ in library path using:

    QCoreApplication::addLibraryPath("/mnt/sdcard/plugins");
    QApplication::addLibraryPath("/mnt/sdcard/plugins");
    

    But this lib-plugin can not be identified.


  • Lifetime Qt Champion

    Are you sure that this path can be accessed as is by your application ?

    By the way, why use such an external path ?



  • @SGaist

    Are you sure that this path can be accessed as is by your application ?

    I have set permission to storage and I can create, read and write a simple text file in this address.

    By the way, why use such an external path ?

    Because when I deploy my app with android studio, I can see all libs like libQt5Core.so and libqsqlite.so in a specific folder and the structure of .../plugins/sqldrivers/libqsqlite.so does not exist. So, I have copied libqsqlite.so to a folder in sdcard by this structure /plugins/sqldrivers/


  • Lifetime Qt Champion

    It has been brought to my attention that my memory may have failed me. See here.

    One thing that you can do is build one of Qt's database example and then inspect the content of the archive generated to see what does mismatch with yours.



  • I can solve the problem. First, I created folder sqldrivers including libqsqlite.so in the app directory (e.x. /data/user/0/com.example.polarislib) and I set permission by chmod 777 to sqldrivers folder and libqsqlite.so file and finally I used the following code in my source where the connection to Sqlite is needed:

    QCoreApplication::addLibraryPath("/data/user/0/com.example.polarislib");