Commit 9dea87d
authored
[Java.Interop] .GetTypeSignature() supports unsigned types (#1312)
Context: dotnet/android#9747
Context: dotnet/android#9812
Context: 71afce5
Context: dotnet/android@aa5e597
Context: dotnet/android@f800c1a
In the ongoing epic to get MAUI running atop NativeAOT, we hit our
longstanding NativeAOT nemesis: a P/Invoke:
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
(`JNIEnv.monodroid_typemap_managed_to_java()` is P/Invoke. Why are
P/Invokes bad? See dotnet/android@f800c1a6.)
The reasonable fix/workaround: update `JNIEnv.FindClass(Type)` to
instead use `JniRuntime.JniTypeManager.GetTypeSignature(Type)`.
(Also known as "embrace more JniRuntime abstractions!".)
Unfortunately, this straightforward idea hits a minor schism between
the .NET for Android and builtin java-interop world orders:
How should Java `byte` be bound?
For starters, what *is* a [Java `byte`][0]?
> The values of the integral types are integers in the following ranges:
>
> * For `byte`, from -128 to 127, inclusive
The Java `byte` is *signed*! Because of that, and because
java-interop originated as a Second System Syndrome rebuild of
Xamarin.Android, *of course* java-interop bound Java `byte` as
`System.SByte`.
.NET for Android, though, bound Java `byte` as `System.Byte`.
This "minor" change meant that lots of unit tests started failing, e.g.
[`NetworkInterfacesTest.DotNetInterfacesShouldEqualJavaInterfaces()`][2]:
System.ArgumentException : Could not determine Java type corresponding to System.Byte[], System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e. Arg_ParamName_Name, type
at Android.Runtime.JNIEnv.FindClass(Type )
at Android.Runtime.JNIEnv.AssertCompatibleArrayTypes(IntPtr , Type )
at Android.Runtime.JNIEnv._GetArray(IntPtr , Type )
at Android.Runtime.JNIEnv.GetArray(IntPtr , JniHandleOwnership , Type )
at Java.Net.NetworkInterface.GetHardwareAddress()
at System.NetTests.NetworkInterfacesTest.GetInfos(IEnumeration interfaces)
at System.NetTests.NetworkInterfacesTest.DotNetInterfacesShouldEqualJavaInterfaces()
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object , BindingFlags )
Rephrased, `runtime.TypeManager.GetTypeSignature(typeof(byte[]))`
returned a "default" `JniTypeSignature` instance.
It's time to reduce the size of this schism.
Update `JniBuiltinMarshalers.GetBuiltInTypeSignature()` so that
`TypeCode.Byte` is treated as a synonym for `TypeCode.SByte`.
This is in fact all that's needed in order to add support for `byte[]`!
Repeat this exercise for all other unsigned types: `ushort`, `uint`,
and `ulong`, as Kotlin unsigned types require it; see also 71afce5
and dotnet/android@aa5e597eba. This fixes the exception:
System.InvalidCastException : Unable to cast from '[I' to '[Ljava/lang/Object;'.
at Android.Runtime.JNIEnv.AssertCompatibleArrayTypes(IntPtr , Type )
at Android.Runtime.JNIEnv._GetArray(IntPtr , Type )
at Android.Runtime.JNIEnv.GetArray(IntPtr , JniHandleOwnership , Type )
at Foo.UnsignedInstanceMethods.UintArrayInstanceMethod(UInt32[] value)
at Xamarin.Android.JcwGenTests.KotlinUnsignedTypesTests.TestUnsignedArrayTypeMembers()
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object , BindingFlags )
This is *not* all that's necessary to fix all dotnet/android tests.
Update `JniRuntime.JniTypeManager.GetTypeSignature()` and
`.GetTypeSignatures()` so that if the type is an open generic type
a `System.NotSupportedException` is thrown instead of a
`System.ArgumentException`. This fixes
[`Java.InteropTests.JnienvTest.NewOpenGenericTypeThrows()`][3].
Also, `JniBuiltinMarshalers.cs` has some hand-made changes, rendering
it out of sync with `JniBuiltinMarshalers.tt`. Update
`JniBuiltinMarshalers.tt` appropriately and regenerate it.
[0]: https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.2.1
[1]: https://github.com/dotnet/java-interop/blob/f30e420a1638dc013302e85dcf76642c10c26832/Documentation/Motivation.md
[2]: https://github.com/dotnet/android/blob/1b1f1452f6b05707418d6605c06e106e6a2a6381/tests/Mono.Android-Tests/Mono.Android-Tests/System.Net/NetworkInterfaces.cs#L107-L137
[3]: https://github.com/dotnet/android/blob/1b1f1452f6b05707418d6605c06e106e6a2a6381/tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/JnienvTest.cs#L107-L1161 parent 1cfb4f4 commit 9dea87d
File tree
4 files changed
+35
-22
lines changed- src/Java.Interop/Java.Interop
- tests/Java.Interop-Tests/Java.Interop
4 files changed
+35
-22
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
| 52 | + | |
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
57 | 58 | | |
| 59 | + | |
58 | 60 | | |
59 | 61 | | |
60 | 62 | | |
| 63 | + | |
61 | 64 | | |
62 | 65 | | |
63 | 66 | | |
| 67 | + | |
64 | 68 | | |
65 | 69 | | |
66 | 70 | | |
| |||
74 | 78 | | |
75 | 79 | | |
76 | 80 | | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | 81 | | |
81 | 82 | | |
82 | 83 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
60 | 65 | | |
61 | 66 | | |
62 | 67 | | |
| |||
68 | 73 | | |
69 | 74 | | |
70 | 75 | | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | 76 | | |
75 | 77 | | |
76 | 78 | | |
| |||
185 | 187 | | |
186 | 188 | | |
187 | 189 | | |
188 | | - | |
| 190 | + | |
189 | 191 | | |
190 | 192 | | |
191 | 193 | | |
| |||
196 | 198 | | |
197 | 199 | | |
198 | 200 | | |
199 | | - | |
| 201 | + | |
200 | 202 | | |
201 | 203 | | |
202 | 204 | | |
| |||
230 | 232 | | |
231 | 233 | | |
232 | 234 | | |
| 235 | + | |
233 | 236 | | |
234 | 237 | | |
235 | 238 | | |
| |||
242 | 245 | | |
243 | 246 | | |
244 | 247 | | |
| 248 | + | |
245 | 249 | | |
246 | 250 | | |
247 | 251 | | |
| |||
256 | 260 | | |
257 | 261 | | |
258 | 262 | | |
259 | | - | |
| 263 | + | |
260 | 264 | | |
261 | 265 | | |
262 | 266 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
149 | | - | |
| 149 | + | |
150 | 150 | | |
151 | 151 | | |
152 | 152 | | |
| |||
184 | 184 | | |
185 | 185 | | |
186 | 186 | | |
187 | | - | |
| 187 | + | |
188 | 188 | | |
189 | 189 | | |
190 | 190 | | |
| |||
Lines changed: 11 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
47 | 53 | | |
48 | 54 | | |
49 | 55 | | |
| |||
89 | 95 | | |
90 | 96 | | |
91 | 97 | | |
| 98 | + | |
92 | 99 | | |
93 | 100 | | |
94 | 101 | | |
| 102 | + | |
95 | 103 | | |
96 | 104 | | |
97 | | - | |
| 105 | + | |
98 | 106 | | |
99 | | - | |
| 107 | + | |
100 | 108 | | |
101 | 109 | | |
102 | 110 | | |
| |||
0 commit comments