Commit 62635a3
committed
[Java.Interop] Support System.Byte, somewhat
Context: dotnet/android#9747
Context: dotnet/android#9812
In the ongoing epic to get MAUI running atop NativeAOT, we hit our
longstanding NativeAOT nemesis: 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.)
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[]`!
It's *not* all that's necessary to fix all unit 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` got some hand-made changes, rendering
it out of sync with `JniBuiltinMarshalers.tt`. 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 f30e420 commit 62635a3
File tree
4 files changed
+19
-8
lines changed- src/Java.Interop/Java.Interop
- tests/Java.Interop-Tests/Java.Interop
4 files changed
+19
-8
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 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
60 | 65 | | |
61 | 66 | | |
62 | 67 | | |
| |||
185 | 190 | | |
186 | 191 | | |
187 | 192 | | |
188 | | - | |
| 193 | + | |
189 | 194 | | |
190 | 195 | | |
191 | 196 | | |
| |||
196 | 201 | | |
197 | 202 | | |
198 | 203 | | |
199 | | - | |
| 204 | + | |
200 | 205 | | |
201 | 206 | | |
202 | 207 | | |
| |||
230 | 235 | | |
231 | 236 | | |
232 | 237 | | |
| 238 | + | |
233 | 239 | | |
234 | 240 | | |
235 | 241 | | |
| |||
242 | 248 | | |
243 | 249 | | |
244 | 250 | | |
| 251 | + | |
245 | 252 | | |
246 | 253 | | |
247 | 254 | | |
| |||
256 | 263 | | |
257 | 264 | | |
258 | 265 | | |
259 | | - | |
| 266 | + | |
260 | 267 | | |
261 | 268 | | |
262 | 269 | | |
| |||
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: 6 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 | | |
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
| |||
89 | 90 | | |
90 | 91 | | |
91 | 92 | | |
| 93 | + | |
92 | 94 | | |
93 | 95 | | |
94 | 96 | | |
| 97 | + | |
95 | 98 | | |
96 | 99 | | |
97 | | - | |
| 100 | + | |
98 | 101 | | |
99 | | - | |
| 102 | + | |
100 | 103 | | |
101 | 104 | | |
102 | 105 | | |
| |||
0 commit comments