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

Cache notification callback JNI class references at startup #1598

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

### Fixed
* Using keypaths in Flows could sometimes throw `java.lang.IllegalStateException: [RLM_ERR_WRONG_THREAD]: Realm accessed from incorrect thread.`. (Issue [#1594](https://github.com/realm/realm-kotlin/pull/1594, since 1.13.0)
* Cache notification callback JNI references at startup to ensure that symbols can be resolved in core callbacks. (Issue [#1577](https://github.com/realm/realm-kotlin/issues/1577))

### Compatibility
* File format: Generates Realms with file format v23.
Expand Down
7 changes: 7 additions & 0 deletions packages/cinterop/src/jvm/jni/java_class_global_def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class JavaClassGlobalDef {
, m_io_realm_kotlin_internal_interop_app_callback(env, "io/realm/kotlin/internal/interop/AppCallback", false)
, m_io_realm_kotlin_internal_interop_connection_state_change_callback(env, "io/realm/kotlin/internal/interop/ConnectionStateChangeCallback", false)
, m_io_realm_kotlin_internal_interop_sync_thread_observer(env, "io/realm/kotlin/internal/interop/SyncThreadObserver", false)
, m_io_realm_kotlin_internal_interop_notification_callback(env, "io/realm/kotlin/internal/interop/NotificationCallback", false)
{
}

Expand All @@ -92,6 +93,7 @@ class JavaClassGlobalDef {
jni_util::JavaClass m_io_realm_kotlin_internal_interop_app_callback;
jni_util::JavaClass m_io_realm_kotlin_internal_interop_connection_state_change_callback;
jni_util::JavaClass m_io_realm_kotlin_internal_interop_sync_thread_observer;
jni_util::JavaClass m_io_realm_kotlin_internal_interop_notification_callback;

inline static std::unique_ptr<JavaClassGlobalDef>& instance()
{
Expand Down Expand Up @@ -219,6 +221,11 @@ class JavaClassGlobalDef {
return instance()->m_io_realm_kotlin_internal_interop_sync_thread_observer;
}

inline static const jni_util::JavaClass& notification_callback()
{
return instance()->m_io_realm_kotlin_internal_interop_notification_callback;
}

inline static const jni_util::JavaMethod function0Method(JNIEnv* env) {
return jni_util::JavaMethod(env, instance()->m_kotlin_jvm_functions_function0, "invoke",
"()Ljava/lang/Object;");
Expand Down
16 changes: 8 additions & 8 deletions packages/jni-swig-stub/src/main/jni/realm_api_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ register_results_notification_cb(realm_results_t *results,
int64_t key_path_array_ptr,
jobject callback) {
auto jenv = get_env();
static jclass notification_class = jenv->FindClass("io/realm/kotlin/internal/interop/NotificationCallback");
static jmethodID on_change_method = jenv->GetMethodID(notification_class, "onChange", "(J)V");
static JavaMethod on_change_method(jenv, JavaClassGlobalDef::notification_callback(),
"onChange", "(J)V");

return realm_results_add_notification_callback(
results,
Expand All @@ -201,8 +201,8 @@ register_results_notification_cb(realm_results_t *results,

realm_on_object_change_func_t get_on_object_change() {
auto jenv = get_env(true);
static jclass notification_class = jenv->FindClass("io/realm/kotlin/internal/interop/NotificationCallback");
static jmethodID on_change_method = jenv->GetMethodID(notification_class, "onChange", "(J)V");
static JavaMethod on_change_method(jenv, JavaClassGlobalDef::notification_callback(),
"onChange", "(J)V");
return [](realm_userdata_t userdata, const realm_object_changes_t* changes) {
// TODO API-NOTIFICATION Consider catching errors and propagate to error callback
// like the C-API error callback below
Expand All @@ -218,8 +218,8 @@ realm_on_object_change_func_t get_on_object_change() {

realm_on_collection_change_func_t get_on_collection_change() {
auto jenv = get_env(true);
static jclass notification_class = jenv->FindClass("io/realm/kotlin/internal/interop/NotificationCallback");
static jmethodID on_change_method = jenv->GetMethodID(notification_class, "onChange", "(J)V");
static JavaMethod on_change_method(jenv, JavaClassGlobalDef::notification_callback(),
"onChange", "(J)V");
return [](realm_userdata_t userdata, const realm_collection_changes_t* changes) {
// TODO API-NOTIFICATION Consider catching errors and propagate to error callback
// like the C-API error callback below
Expand All @@ -235,8 +235,8 @@ realm_on_collection_change_func_t get_on_collection_change() {

realm_on_dictionary_change_func_t get_on_dictionary_change() {
auto jenv = get_env(true);
static jclass notification_class = jenv->FindClass("io/realm/kotlin/internal/interop/NotificationCallback");
static jmethodID on_change_method = jenv->GetMethodID(notification_class, "onChange", "(J)V");
static JavaMethod on_change_method(jenv, JavaClassGlobalDef::notification_callback(),
"onChange", "(J)V");
return [](realm_userdata_t userdata, const realm_dictionary_changes_t* changes) {
// TODO API-NOTIFICATION Consider catching errors and propagate to error callback
// like the C-API error callback below
Expand Down