diff --git a/src/Mono.Android/Java.Interop/TypeManager.cs b/src/Mono.Android/Java.Interop/TypeManager.cs index 9d71981804f..c0993e1a9d9 100644 --- a/src/Mono.Android/Java.Interop/TypeManager.cs +++ b/src/Mono.Android/Java.Interop/TypeManager.cs @@ -267,7 +267,7 @@ internal static IJavaPeerable CreateInstance (IntPtr handle, JniHandleOwnership { Type? type = null; IntPtr class_ptr = JNIEnv.GetObjectClass (handle); - string class_name = GetClassName (class_ptr); + string? class_name = GetClassName (class_ptr); lock (TypeManagerMapDictionaries.AccessLock) { while (class_ptr != IntPtr.Zero && !TypeManagerMapDictionaries.JniToManaged.TryGetValue (class_name, out type)) { @@ -279,12 +279,18 @@ internal static IJavaPeerable CreateInstance (IntPtr handle, JniHandleOwnership IntPtr super_class_ptr = JNIEnv.GetSuperclass (class_ptr); JNIEnv.DeleteLocalRef (class_ptr); + class_name = null; class_ptr = super_class_ptr; - class_name = GetClassName (class_ptr); + if (class_ptr != IntPtr.Zero) { + class_name = GetClassName (class_ptr); + } } } - JNIEnv.DeleteLocalRef (class_ptr); + if (class_ptr != IntPtr.Zero) { + JNIEnv.DeleteLocalRef (class_ptr); + class_ptr = IntPtr.Zero; + } if (targetType != null && (type == null || diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index 82b7607f437..ac6fddfd36b 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -695,6 +695,30 @@ EmbeddedAssemblies::typemap_java_to_managed (hash_t hash, const MonoString *java if (module->image == nullptr) { module->image = mono_image_loaded (module->assembly_name); + + if (module->image == nullptr) { + log_debug (LOG_ASSEMBLY, "typemap: assembly '%s' hasn't been loaded yet, attempting a full load", module->assembly_name); + + // Fake a request from MonoVM to load the assembly. + MonoAssemblyName *assembly_name = mono_assembly_name_new (module->assembly_name); + MonoAssembly *assm; + + if (assembly_name == nullptr) { + log_error (LOG_ASSEMBLY, "typemap: failed to create Mono assembly name for '%s'", module->assembly_name); + assm = nullptr; + } else { + MonoAssemblyLoadContextGCHandle alc_gchandle = mono_alc_get_default_gchandle (); + MonoError mono_error; + assm = embeddedAssemblies.open_from_bundles (assembly_name, alc_gchandle, &mono_error, false /* ref_only */); + } + + if (assm == nullptr) { + log_warn (LOG_ASSEMBLY, "typemap: failed to load managed assembly '%s'", module->assembly_name); + } else { + module->image = mono_assembly_get_image (assm); + } + } + if (module->image == nullptr) { log_error (LOG_ASSEMBLY, "typemap: unable to load assembly '%s' when looking up managed type corresponding to Java type '%s'", module->assembly_name, to_utf8 (java_type_name).get ()); return nullptr; diff --git a/src/monodroid/jni/osbridge.cc b/src/monodroid/jni/osbridge.cc index 067e9019da4..f7ca9467243 100644 --- a/src/monodroid/jni/osbridge.cc +++ b/src/monodroid/jni/osbridge.cc @@ -657,15 +657,13 @@ OSBridge::add_reference_jobject (JNIEnv *env, jobject handle, jobject reffed_han java_class = env->GetObjectClass (handle); add_method_id = env->GetMethodID (java_class, "monodroidAddReference", "(Ljava/lang/Object;)V"); + env->DeleteLocalRef (java_class); if (add_method_id) { env->CallVoidMethod (handle, add_method_id, reffed_handle); - env->DeleteLocalRef (java_class); - return 1; } env->ExceptionClear (); - env->DeleteLocalRef (java_class); return 0; } @@ -910,7 +908,6 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri MonoClass *klass; #endif MonoObject *obj; - jclass java_class; jobject jref; jmethodID clear_method_id; int i, j, total, alive, refs_added; @@ -942,8 +939,9 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri sccs [i]->is_alive = 1; mono_field_get_value (obj, bridge_info->refs_added, &refs_added); if (refs_added) { - java_class = env->GetObjectClass (jref); + jclass java_class = env->GetObjectClass (jref); clear_method_id = env->GetMethodID (java_class, "monodroidClearReferences", "()V"); + env->DeleteLocalRef (java_class); if (clear_method_id) { env->CallVoidMethod (jref, clear_method_id); } else { @@ -957,7 +955,6 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri } #endif } - env->DeleteLocalRef (java_class); } } else { abort_unless (!sccs [i]->is_alive, "Bridge SCC at index %d must NOT be alive", i);