Android: check if objectClass() is not null in registerNativeMethods()

In case the class doens't have a default constructor, checking for
object.isValid() will give false because the object won't be created,
however, the class could still be loaded and we could have a valid
jclass.

Pick-to: 6.2
Fixes: QTBUG-96069
Change-Id: I8d59e26d9d7c0e8e363ce443937091a374a24473
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
bb10
Assam Boudjelthia 2021-11-01 19:54:22 +02:00
parent f3e2689106
commit dfb4b7856a
3 changed files with 53 additions and 16 deletions

View File

@ -347,11 +347,12 @@ JavaVM *QJniEnvironment::javaVM()
bool QJniEnvironment::registerNativeMethods(const char *className, const JNINativeMethod methods[],
int size)
{
QJniObject classObject(className);
const jclass clazz = findClass(className);
if (!classObject.isValid())
if (!clazz)
return false;
return registerNativeMethods(classObject.objectClass(), methods, size);
return registerNativeMethods(clazz, methods, size);
}
#if QT_DEPRECATED_SINCE(6, 2)
/*!

View File

@ -49,3 +49,13 @@ public class QtJniEnvironmentTestClass
}
}
class QtJniEnvironmentTestClassNoCtor
{
private static native void callbackFromJavaNoCtor(String message);
public static void appendJavaToString(String message)
{
callbackFromJavaNoCtor("From Java (no ctor): " + message);
}
}

View File

@ -34,6 +34,8 @@
static const char javaTestClass[] =
"org/qtproject/qt/android/testdatapackage/QtJniEnvironmentTestClass";
static const char javaTestClassNoCtor[] =
"org/qtproject/qt/android/testdatapackage/QtJniEnvironmentTestClassNoCtor";
static QString registerNativesString = QStringLiteral("Qt");
static int registerNativeInteger = 0;
@ -122,22 +124,46 @@ static void callbackFromJava(JNIEnv *env, jobject /*thiz*/, jstring value)
registerNativesString = QJniObject(value).toString();
}
static void callbackFromJavaNoCtor(JNIEnv *env, jobject /*thiz*/, jstring value)
{
Q_UNUSED(env)
registerNativesString = QJniObject(value).toString();
}
void tst_QJniEnvironment::registerNativeMethods()
{
const JNINativeMethod methods[] {
{"callbackFromJava", "(Ljava/lang/String;)V", reinterpret_cast<void *>(callbackFromJava)}
};
QJniEnvironment env;
QVERIFY(env.registerNativeMethods(javaTestClass, methods, 1));
QJniObject QtString = QJniObject::fromString(registerNativesString);
QJniObject::callStaticMethod<void>(javaTestClass,
"appendJavaToString",
"(Ljava/lang/String;)V",
QtString.object<jstring>());
QTest::qWait(200);
QVERIFY(registerNativesString == QStringLiteral("From Java: Qt"));
QJniEnvironment env;
{
const JNINativeMethod methods[] {
{"callbackFromJava", "(Ljava/lang/String;)V", reinterpret_cast<void *>(callbackFromJava)}
};
QVERIFY(env.registerNativeMethods(javaTestClass, methods, 1));
QJniObject::callStaticMethod<void>(javaTestClass,
"appendJavaToString",
"(Ljava/lang/String;)V",
QtString.object<jstring>());
QTest::qWait(200);
QVERIFY(registerNativesString == QStringLiteral("From Java: Qt"));
}
// No default constructor in class
{
const JNINativeMethod methods[] {{"callbackFromJavaNoCtor", "(Ljava/lang/String;)V",
reinterpret_cast<void *>(callbackFromJavaNoCtor)}};
QVERIFY(env.registerNativeMethods(javaTestClassNoCtor, methods, 1));
QJniObject::callStaticMethod<void>(javaTestClassNoCtor,
"appendJavaToString",
"(Ljava/lang/String;)V",
QtString.object<jstring>());
QTest::qWait(200);
QVERIFY(registerNativesString == QStringLiteral("From Java (no ctor): Qt"));
}
}
static void intCallbackFromJava(JNIEnv *env, jobject /*thiz*/, jint value)