From 061b52bae2f932ce9f85b1abe053f9056fbd8c8a Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Fri, 7 Feb 2025 14:59:32 -0600 Subject: [PATCH] [Mono.Android] update `JNIEnv.FindClass()` to use `JniEnvironment.Types.FindClass()` This avoids the problem of `JNIEnvInit.mid_Class_forName` being `null` in a NativeAOT context: 02-07 14:05:25.954 30744 30744 E AndroidRuntime: Process: net.dot.hellonativeaot, PID: 30744 02-07 14:05:25.954 30744 30744 E AndroidRuntime: net.dot.jni.internal.JavaProxyThrowable: System.TypeInitializationException: TypeInitialization_Type_NoTypeAvailable 02-07 14:05:25.954 30744 30744 E AndroidRuntime: ---> System.ArgumentNullException: ArgumentNull_Generic Arg_ParamName_Name, method 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Java.Interop.JniEnvironment.StaticMethods.CallStaticObjectMethod(JniObjectReference, JniMethodInfo, JniArgumentValue*) + 0x1c8 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Android.Runtime.JNIEnv.FindClass(String) + 0xb4 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Java.Lang.Class..cctor() + 0x7c 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0xb4 02-07 14:05:25.954 30744 30744 E AndroidRuntime: Exception_EndOfInnerExceptionStack 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x160 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at System.Runtime.CompilerServices.ClassConstructorRunner.CheckStaticClassConstructionReturnNonGCStaticBase(StaticClassConstructionContext*, IntPtr) + 0x14 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Android.Runtime.JNIEnv.FindClass(String) + 0xc0 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Android.App.Application.get_Context() + 0x50 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.Hosting.EssentialsExtensions.<>c.b__0_0(ILifecycleBuilder life) + 0x18 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.LifecycleEvents.LifecycleEventService..ctor(IEnumerable`1) + 0x94 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.LifecycleEvents.MauiAppHostBuilderExtensions.<>c.b__0_0(IServiceProvider sp) + 0x3c 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite, RuntimeResolverContext) + 0x68 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier) + 0x180 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey, Func`2) + 0x11c 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier, ServiceProviderEngineScope) + 0x44 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.MauiContext.WrappedServiceProvider.GetService(Type) + 0x48 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.MauiContext.WrappedServiceProvider.GetService(Type) + 0x48 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider) + 0x3c 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.LifecycleEvents.LifecycleEventServiceExtensions.d__3`1.MoveNext() + 0x38 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.LifecycleEvents.LifecycleEventServiceExtensions.InvokeLifecycleEvents[TDelegate](IServiceProvider, Action`1) + 0x68 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Microsoft.Maui.MauiApplication.OnCreate() + 0xb0 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at Android.App.Application.n_OnCreate(IntPtr jnienv, IntPtr native__this) + 0xb0 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at my.MainApplication.n_onCreate(Native Method) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at my.MainApplication.onCreate(MainApplication.java:24) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1386) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7398) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2379) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:107) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:232) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.os.Looper.loop(Looper.java:317) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8592) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580) 02-07 14:05:25.954 30744 30744 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:878) This also allows us to remove these that are now unused: * `JnienvInitializeArgs.Class_forName` * `JNIEnv.BinaryName()` --- src/Mono.Android/Android.Runtime/JNIEnv.cs | 47 +------------------ .../Android.Runtime/JNIEnvInit.cs | 4 -- .../mono/monodroid/monodroid-glue-internal.hh | 1 - src/native/mono/monodroid/monodroid-glue.cc | 1 - 4 files changed, 2 insertions(+), 51 deletions(-) diff --git a/src/Mono.Android/Android.Runtime/JNIEnv.cs b/src/Mono.Android/Android.Runtime/JNIEnv.cs index 73530406da5..9cf5207f6af 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnv.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnv.cs @@ -280,52 +280,9 @@ public static IntPtr FindClass (System.Type type) } } - const int nameBufferLength = 1024; - [ThreadStatic] static char[]? nameBuffer; - - static unsafe IntPtr BinaryName (string classname) + public static IntPtr FindClass (string classname) { - int index = classname.IndexOf ('/'); - - if (index == -1) - return NewString (classname); - - int length = classname.Length; - if (length > nameBufferLength) - return NewString (classname.Replace ('/', '.')); - - if (nameBuffer == null) - nameBuffer = new char[nameBufferLength]; - - fixed (char* src = classname, dst = nameBuffer) { - char* src_ptr = src; - char* dst_ptr = dst; - char* end_ptr = src + length; - while (src_ptr < end_ptr) { - *dst_ptr = (*src_ptr == '/') ? '.' : *src_ptr; - src_ptr++; - dst_ptr++; - } - } - return NewString (nameBuffer, length); - } - - public unsafe static IntPtr FindClass (string classname) - { - JniObjectReference local_ref; - - IntPtr native_str = BinaryName (classname); - try { - JniArgumentValue* parameters = stackalloc JniArgumentValue [3] { - new JniArgumentValue (native_str), - new JniArgumentValue (true), - new JniArgumentValue (JNIEnvInit.java_class_loader), - }; - local_ref = JniEnvironment.StaticMethods.CallStaticObjectMethod (Java.Lang.Class.Members.JniPeerType.PeerReference, JNIEnvInit.mid_Class_forName!, parameters); - } finally { - DeleteLocalRef (native_str); - } - + JniObjectReference local_ref = JniEnvironment.Types.FindClass (classname); IntPtr global_ref = NewGlobalRef (local_ref.Handle); JniObjectReference.Dispose (ref local_ref); return global_ref; diff --git a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs index cb1f39a8ec5..2499b693cf2 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs @@ -20,7 +20,6 @@ internal struct JnienvInitializeArgs { public IntPtr grefLoader; public IntPtr Loader_loadClass; public IntPtr grefClass; // TODO: remove, not needed anymore - public IntPtr Class_forName; public uint logCategories; public int version; // TODO: remove, not needed anymore public int grefGcThreshold; @@ -46,7 +45,6 @@ internal struct JnienvInitializeArgs { internal static IntPtr grefIGCUserPeer_class; internal static IntPtr grefGCUserPeerable_class; internal static IntPtr java_class_loader; - internal static JniMethodInfo? mid_Class_forName; internal static JniRuntime? androidRuntime; @@ -100,8 +98,6 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args) MarshalMethodsEnabled = args->marshalMethodsEnabled; java_class_loader = args->grefLoader; - mid_Class_forName = new JniMethodInfo (args->Class_forName, isStatic: true); - BoundExceptionType = (BoundExceptionType)args->ioExceptionType; androidRuntime = new AndroidRuntime (args->env, args->javaVm, args->grefLoader, args->Loader_loadClass, args->jniAddNativeMethodRegistrationAttributePresent != 0); ValueManager = androidRuntime.ValueManager; diff --git a/src/native/mono/monodroid/monodroid-glue-internal.hh b/src/native/mono/monodroid/monodroid-glue-internal.hh index c32882702bb..36c9206e36d 100644 --- a/src/native/mono/monodroid/monodroid-glue-internal.hh +++ b/src/native/mono/monodroid/monodroid-glue-internal.hh @@ -89,7 +89,6 @@ namespace xamarin::android::internal jobject grefLoader; jmethodID Loader_loadClass; jclass grefClass; - jmethodID Class_forName; unsigned int logCategories; int version; int grefGcThreshold; diff --git a/src/native/mono/monodroid/monodroid-glue.cc b/src/native/mono/monodroid/monodroid-glue.cc index 94e4944616c..ebb72718c57 100644 --- a/src/native/mono/monodroid/monodroid-glue.cc +++ b/src/native/mono/monodroid/monodroid-glue.cc @@ -860,7 +860,6 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec init.grefClass = RuntimeUtil::get_class_from_runtime_field (env, runtimeClass, "java_lang_Class", true); Class_getName = env->GetMethodID (init.grefClass, "getName", "()Ljava/lang/String;"); - init.Class_forName = env->GetStaticMethodID (init.grefClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"); MonoAssembly *mono_android_assembly;