I am new to JNI and this is my first program trying to call Java code from C ++. I am using Qt 5.2 and I am writing an Android application.
I cannot find my java class and load it into my C ++ program. I read a lot of posts here about stack overflows and other places, and this seems to be a common problem, but I have not been able to solve my problem yet.
I'm also not sure if the Java virtual machine is installed correctly, since the Qt documentation in QAndroidJniEnvironment is minimal.
I am looking for a solution on how to find my java class. I also evaluate general feedback on other sections of the code (I assume there may be more errors).
Msg error:
Starting remote process.D/dalvikvm(24911): GC_CONCURRENT freed 384K, 5% free 9180K/9596K, paused 1ms+2ms, total 15ms D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360 D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360, skipping init D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Core.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Core.so 0x428b2360 D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Network.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Network.so 0x428b2360 I/Qt (24911): Network start D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360 D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360, skipping init D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360 D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360, skipping init D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360 D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360, skipping init D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360 D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360, skipping init D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360 D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360, skipping init D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/plugins/platforms/android/libqtforandroidGL.so 0x428b2360 D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/plugins/platforms/android/libqtforandroidGL.so 0x428b2360 I/Qt (24911): qt start W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtMessageDialogHelper' D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360 D/dalvikvm(24911): Shared lib '/data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so' already loaded in same CL 0x428b2360 D/dalvikvm(24911): Trying to load lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360 D/Qt (24911): qml\qqmlengine.cpp:1451 (QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool)): QML debugging is enabled. Only use this in a safe environment. D/dalvikvm(24911): Added shared lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360 D/dalvikvm(24911): No JNI_OnLoad found in /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360, skipping init W/Qt (24911): kernel\qcoreapplication.cpp:416 (QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, uint)): WARNING: QApplication was not created in the main() thread. W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtNativeInputConnection' W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtExtractedText' I/Adreno-EGL(24911): <qeglDrvAPI_eglInitialize:320>: EGL 1.4 QUALCOMM Build: I0404c4692afb8623f95c43aeb6d5e13ed4b30ddbDate: 11/06/13 D/Qt (24911): fontdatabases\basic\qbasicfontdatabase.cpp:246 (static QStringList QBasicFontDatabase::addTTFile(const QByteArray&, const QByteArray&)): FT_New_Face failed with index 0 : 90 D/Qt (24911): ..\AndroidTest\jnimathcppwrapper.cpp:18 (jniMathCppWrapper::jniMathCppWrapper()): JniMath class not found D/Qt (24911): ..\AndroidTest\jnimathcppwrapper.cpp:43 (int jniMathCppWrapper::eleven()): Enter eleven F/libc (24911): Fatal signal 11 (SIGSEGV) at 0x0000002c (code=1), thread 24933 (ple.AndroidTest)
Java class:
package org.app.test; public class JniMath { public JniMath() { } public int eleven() { return 11; } }
.pro file:
main.cpp:
#include <QtGui/QGuiApplication> #include "qtquick2applicationviewer.h" #include "jnimathcppwrapper.h" #include <QDebug> #include <QString> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QtQuick2ApplicationViewer viewer; viewer.setMainQmlFile(QStringLiteral("qml/AndroidTest/main.qml")); viewer.showExpanded(); jniMathCppWrapper *test = new jniMathCppWrapper(); qDebug() << QString::number(test->eleven()); return app.exec(); }
jnimathcppwrapper.h:
#ifndef JNIMATHCPPWRAPPER_H #define JNIMATHCPPWRAPPER_H #include <QtAndroidExtras> class jniMathCppWrapper { public: jniMathCppWrapper(); int eleven(); private: jobject jniMathObject; }; #endif // JNIMATHCPPWRAPPER_H
jnimathcppwrapper.cpp:
#include "jnimathcppwrapper.h" #include <QtAndroidExtras> #include <QDebug> #include <jni.h> static jclass jniMathClassID = 0; static jmethodID jniMathConstructorMethodID = 0; static jmethodID jniMathElevenMethodID = 0; jniMathCppWrapper::jniMathCppWrapper() { QAndroidJniEnvironment qjniEnv; //Get JniMath class ID. jniMathClassID = qjniEnv->FindClass("android/src/org/app/test/JniMath"); if(jniMathClassID == NULL) { qDebug() << "JniMath class not found"; return; } //Get constructor method ID jniMathConstructorMethodID = qjniEnv->GetMethodID(jniMathClassID, "<init>", "void(V)"); if(jniMathConstructorMethodID == NULL) { qDebug() << "JniMath constructor not found"; return; } //Create new Java object and calling the selected constructor. jniMathObject = qjniEnv->NewObject(jniMathClassID, jniMathConstructorMethodID); if(jniMathObject == NULL) { qDebug() << "JniMath Java object could not be constructed"; return; } } int jniMathCppWrapper::eleven() { QAndroidJniEnvironment qjniEnv; qDebug() << "Enter eleven"; //Get eleven method ID jniMathElevenMethodID = qjniEnv->GetMethodID(jniMathClassID, "eleven", "void(V)"); if(jniMathElevenMethodID == NULL) { qDebug() << "JniMath class, eleven method not found"; return 9; } jint res = qjniEnv->CallIntMethod(jniMathObject, jniMathElevenMethodID); return (int) res; }
Project Structure:

EDIT:
I also tried a different approach that led to the same error:
QAndroidJniObject *myJavaClass = new QAndroidJniObject("android/src/org/app/test/JniMath"); if(myJavaClass->isValid()) { qDebug() << "Class found!"; } else { qDebug() << "Class NOT found!"; }
When trying to load java / lang / String, both methods above will find the class.
EDIT:
Error Log:
D/Qt ( 3385): qml\qqmlengine.cpp:1451 (QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool)): QML debugging is enabled. Only use this in a safe environment. D/dalvikvm( 3385): Added shared lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b67f8 D/Qt ( 3385): ..\AndroidTest\jnimathcppwrapper.cpp:68 (jint JNI_OnLoad(JavaVM*, void*)): Class NOT found D/AndroidRuntime( 3385): Shutting down VM W/dalvikvm( 3385): threadid=1: thread exiting with uncaught exception (group=0x41fecba8) E/AndroidRuntime( 3385): FATAL EXCEPTION: main E/AndroidRuntime( 3385): Process: org.qtproject.example.AndroidTest, PID: 3385 E/AndroidRuntime( 3385): java.lang.NoClassDefFoundError: org/app/test/JniMath E/AndroidRuntime( 3385): at java.lang.Runtime.nativeLoad(Native Method) E/AndroidRuntime( 3385): at java.lang.Runtime.doLoad(Runtime.java:421) E/AndroidRuntime( 3385): at java.lang.Runtime.loadLibrary(Runtime.java:362) E/AndroidRuntime( 3385): at java.lang.System.loadLibrary(System.java:526) E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:235) E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:522) E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:744) E/AndroidRuntime( 3385): at android.app.Activity.performCreate(Activity.java:5231) W/dalvikvm( 3385): threadid=1: thread exiting with uncaught exception (group=0x41fecba8) E/AndroidRuntime( 3385): FATAL EXCEPTION: main E/AndroidRuntime( 3385): Process: org.qtproject.example.AndroidTest, PID: 3385 E/AndroidRuntime( 3385): java.lang.NoClassDefFoundError: org/app/test/JniMath E/AndroidRuntime( 3385): at java.lang.Runtime.nativeLoad(Native Method) E/AndroidRuntime( 3385): at java.lang.Runtime.doLoad(Runtime.java:421) E/AndroidRuntime( 3385): at java.lang.Runtime.loadLibrary(Runtime.java:362) E/AndroidRuntime( 3385): at java.lang.System.loadLibrary(System.java:526) E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:235) E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:522) E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:744) E/AndroidRuntime( 3385): at android.app.Activity.performCreate(Activity.java:5231) E/AndroidRuntime( 3385): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) E/AndroidRuntime( 3385): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159) E/AndroidRuntime( 3385): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) E/AndroidRuntime( 3385): at android.app.ActivityThread.access$800(ActivityThread.java:135) E/AndroidRuntime( 3385): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) E/AndroidRuntime( 3385): at android.os.Handler.dispatchMessage(Handler.java:102) E/AndroidRuntime( 3385): at android.os.Looper.loop(Looper.java:136) E/AndroidRuntime( 3385): at android.app.ActivityThread.main(ActivityThread.java:5017) E/AndroidRuntime( 3385): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime( 3385): at java.lang.reflect.Method.invoke(Method.java:515) E/AndroidRuntime( 3385): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) E/AndroidRuntime( 3385): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) E/AndroidRuntime( 3385): at dalvik.system.NativeStart.main(Native Method) E/AndroidRuntime( 3385): Caused by: java.lang.ClassNotFoundException: Didn't find class "org.app.test.JniMath" on path: DexPathList[[zip file "/data/app/org.qtproject.example.AndroidTest-1.apk"],nativeLibraryDirectories=[/data/app-lib/org.qtproject.example.AndroidTest-1, /vendor/lib, /system/lib]] E/AndroidRuntime( 3385): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) E/AndroidRuntime( 3385): at java.lang.ClassLoader.loadClass(ClassLoader.java:497) E/AndroidRuntime( 3385): at java.lang.ClassLoader.loadClass(ClassLoader.java:457) E/AndroidRuntime( 3385): ... 21 more
Comment: why this question is not a duplicate (by Alex Cohn)
There is no doubt that the root problem here is the same as in FindClass from any thread in Android JNI , but the question asked here is a completely different question - IMO. The author did not look for a general way to access ClassLoader from their own threads. He (or she) was looking for a simple and efficient way to access Java callbacks from native Qt-based code. Therefore, all the discussions about how the class loader works in Android and how this can be fixed does not matter to him. If the author thinks otherwise, I would be happy to agree to close this question as a duplicate
Update: this question is not even related to JNI threads
Please review the previous void comment. This question has nothing to do with multithreading. It's all about how to set up a Qt application for Android so that it can use custom Java classes similar to the sample .