Skip to content

Commit

Permalink
Bump to dotnet/java-interop@9dea87dc; FindClass & TypeManager (#9812)
Browse files Browse the repository at this point in the history
Changes: dotnet/java-interop@f30e420...9dea87d

  * dotnet/java-interop@9dea87dc: [Java.Interop] .GetTypeSignature() supports unsigned types (dotnet/java-interop#1312)
  * dotnet/java-interop@1cfb4f4d: [generator] Add support for emitting `[UnsupportedOSPlatform]` (dotnet/java-interop#1307)

Context: #9811

The .NET MAUI template + NativeAOT currently crashes with:

	E AndroidRuntime: net.dot.jni.internal.JavaProxyThrowable: System.InvalidProgramException: InvalidProgram_Specific, IntPtr Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(System.Type, Byte*)
	E AndroidRuntime:    at Internal.Runtime.TypeLoaderExceptionHelper.CreateInvalidProgramException(ExceptionStringID, String) + 0x4c
	E AndroidRuntime:    at Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(Type, Byte*) + 0x18
	E AndroidRuntime:    at Android.Runtime.JNIEnv.TypemapManagedToJava(Type) + 0x104
	E AndroidRuntime:    at Android.Runtime.JNIEnv.GetJniName(Type) + 0x1c
	E AndroidRuntime:    at Android.Runtime.JNIEnv.FindClass(Type) + 0x38
	E AndroidRuntime:    at Android.Runtime.JNIEnv.NewArray(IJavaObject[]) + 0x28
	E AndroidRuntime:    at Android.Runtime.JNIEnv.NewArray[T](T[]) + 0x94
	E AndroidRuntime:    at Android.Graphics.Drawables.LayerDrawable..ctor(Drawable[] layers) + 0xd4
	E AndroidRuntime:    at Microsoft.Maui.Platform.MauiRippleDrawableExtensions.UpdateMauiRippleDrawableBackground(View, Paint, IButtonStroke, Func`1, Func`1, Action) + 0x2ac

This appears to be related to array usage, such as
`LayerDrawable.ctor(Drawable[])` in this example.

I can reproduce the same crash using a
`ColorStateList.ctor(int[][], int[])` in `samples/NativeAOT`:

	E AndroidRuntime: net.dot.jni.internal.JavaProxyThrowable: System.InvalidProgramException: InvalidProgram_Specific, IntPtr Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(System.Type, Byte*)
	E AndroidRuntime:    at Internal.Runtime.TypeLoaderExceptionHelper.CreateInvalidProgramException(ExceptionStringID, String) + 0x4c
	E AndroidRuntime:    at Android.Runtime.JNIEnv.monodroid_typemap_managed_to_java(Type, Byte*) + 0x18
	E AndroidRuntime:    at Android.Runtime.JNIEnv.TypemapManagedToJava(Type) + 0x104
	E AndroidRuntime:    at Android.Runtime.JNIEnv.GetJniName(Type) + 0x1c
	E AndroidRuntime:    at Android.Runtime.JNIEnv.FindClass(Type) + 0x38
	E AndroidRuntime:    at Android.Runtime.JNIEnv.NewArray[T](T[]) + 0xa8
	E AndroidRuntime:    at Android.Content.Res.ColorStateList..ctor(Int32[][], Int32[]) + 0xdc
	E AndroidRuntime:    at NativeAOT.MainActivity.OnCreate(Bundle savedInstanceState) + 0xb8

Update `JNIEnv.FindClass(Type)` to go through `TypeManager` instead
of using `TypemapManagedToJava`.  This avoids the P/Invoke which is
causing the crash (f800c1a).

Note that we can't directly use
`JniRuntime.JniTypeManager.GetTypeSignature()`, as the previous use
of `JavaNativeTypeManager.ToJniName(Type)` would default to using
`java/lang/Object` if there was no typemap entry for `type`.

After this change, the sample works and prints a log message
indicating `ColorStateList` is created successfully:

	D NativeAOT: MainActivity.OnCreate() ColorStateList: ColorStateList{mThemeAttrs=nullmChangingConfigurations=0mStateSpecs=[[0, 1]]mColors=[0, 1]mDefaultColor=0}
  • Loading branch information
jonathanpeppers authored Feb 21, 2025
1 parent 32c8bf6 commit f45700f
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
5 changes: 5 additions & 0 deletions samples/NativeAOT/MainActivity.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Android.Content.Res;
using Android.Runtime;
using Android.Util;
using System.Reflection;
Expand All @@ -17,5 +18,9 @@ protected override void OnCreate(Bundle? savedInstanceState)

// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);

// An example of an Android API that uses a Java array
var list = new ColorStateList (new int[][] { [ 0, 1 ]}, [0, 1]);
Log.Debug ("NativeAOT", "MainActivity.OnCreate() ColorStateList: " + list);
}
}
11 changes: 10 additions & 1 deletion src/Mono.Android/Android.Runtime/JNIEnv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,16 @@ public static IntPtr FindClass (System.Type type)
{
int rank = JavaNativeTypeManager.GetArrayInfo (type, out type);
try {
return FindClass (JavaNativeTypeManager.ToJniName (GetJniName (type), rank));
var sig = JNIEnvInit.androidRuntime?.TypeManager.GetTypeSignature (type) ?? default;
if (!sig.IsValid || sig.SimpleReference == null) {
sig = new JniTypeSignature ("java/lang/Object");
}
sig = sig.AddArrayRank (rank);

JniObjectReference local_ref = JniEnvironment.Types.FindClass (sig.Name);
IntPtr global_ref = local_ref.NewGlobalRef ().Handle;
JniObjectReference.Dispose (ref local_ref);
return global_ref;
} catch (Java.Lang.Throwable e) {
if (!((e is Java.Lang.NoClassDefFoundError) || (e is Java.Lang.ClassNotFoundException)))
throw;
Expand Down

0 comments on commit f45700f

Please sign in to comment.