From cd152dd5367fab1a8a0b83c9572b567384117a3e Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Sat, 29 Jun 2024 09:27:51 -0400 Subject: [PATCH 1/4] Try dotnet/java-interop#1234 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: https://github.com/dotnet/java-interop/pull/1234 Does It Build™? --- .gitmodules | 2 +- external/Java.Interop | 2 +- .../Java.Interop/JavaObjectExtensionsTests.cs | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index ea5f83ceb43..00b83da1a59 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,7 +13,7 @@ [submodule "external/Java.Interop"] path = external/Java.Interop url = https://github.com/dotnet/java-interop - branch = main + branch = dev/jonp/jonp-add-JavaAs [submodule "external/libunwind"] path = external/libunwind url = https://github.com/libunwind/libunwind.git diff --git a/external/Java.Interop b/external/Java.Interop index ccafbe6a102..647a22b96f3 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit ccafbe6a102a85efe84ceb210b3b8b93e49edbcb +Subproject commit 647a22b96f32a6c0deef4d883fc80239df583957 diff --git a/tests/Mono.Android-Tests/Java.Interop/JavaObjectExtensionsTests.cs b/tests/Mono.Android-Tests/Java.Interop/JavaObjectExtensionsTests.cs index d936393c032..e6b133a4eaf 100644 --- a/tests/Mono.Android-Tests/Java.Interop/JavaObjectExtensionsTests.cs +++ b/tests/Mono.Android-Tests/Java.Interop/JavaObjectExtensionsTests.cs @@ -56,6 +56,14 @@ public void JavaCast_CheckForManagedSubclasses () } } + [Test] + public void JavaAs () + { + using var v = new Java.InteropTests.MyJavaInterfaceImpl (); + using var c = v.JavaAs(); + Assert.IsNotNull (c); + } + static Java.Lang.Object CreateObject () { var ctor = JNIEnv.GetMethodID (Java.Lang.Class.Object, "", "()V"); From ff2656949f50a217b43635cf05178c76644f2768 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 3 Jul 2024 17:48:04 -0400 Subject: [PATCH 2/4] Fix tests. Fascinating "corner case" discovered: `AndroidValueManager.CreatePeer()` didn't do a Java-side type check, and thus would allow anything to be "cast to" anything. (The `.JavaCast()` extension method *did* check things, so the most likely codepath worked properly, but not this one.) Fix `AndroidValueManager.CreatePeer()`, bump Java.Interop. Hopefully *now* all unit tests pass. --- external/Java.Interop | 2 +- .../Android.Runtime/JNIEnvInit.cs | 2 +- src/Mono.Android/Java.Interop/TypeManager.cs | 22 ++++++++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/external/Java.Interop b/external/Java.Interop index 647a22b96f3..31045b80bbc 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 647a22b96f32a6c0deef4d883fc80239df583957 +Subproject commit 31045b80bbc70efe9dc7ef7ace4862804d716b7f diff --git a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs index 2b3bed66a3c..7ac2bdf2a39 100644 --- a/src/Mono.Android/Android.Runtime/JNIEnvInit.cs +++ b/src/Mono.Android/Android.Runtime/JNIEnvInit.cs @@ -50,7 +50,7 @@ internal struct JnienvInitializeArgs { internal static IntPtr java_class_loader; internal static JniMethodInfo? mid_Class_forName; - static AndroidRuntime? androidRuntime; + internal static AndroidRuntime? androidRuntime; [UnmanagedCallersOnly] static unsafe void RegisterJniNatives (IntPtr typeName_ptr, int typeName_len, IntPtr jniClass, IntPtr methods_ptr, int methods_len) diff --git a/src/Mono.Android/Java.Interop/TypeManager.cs b/src/Mono.Android/Java.Interop/TypeManager.cs index fb4e87216a4..606051530e9 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 [UnconditionalSuppressMessage ("Trimming", "IL2067", Justification = "TypeManager.CreateProxy() does not statically know the value of the 'type' local variable.")] [UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "TypeManager.CreateProxy() does not statically know the value of the 'type' local variable.")] - internal static IJavaPeerable CreateInstance (IntPtr handle, JniHandleOwnership transfer, Type? targetType) + internal static IJavaPeerable? CreateInstance (IntPtr handle, JniHandleOwnership transfer, Type? targetType) { Type? type = null; IntPtr class_ptr = JNIEnv.GetObjectClass (handle); @@ -318,6 +318,26 @@ internal static IJavaPeerable CreateInstance (IntPtr handle, JniHandleOwnership type = invokerType; } + var typeSig = JNIEnvInit.androidRuntime?.TypeManager.GetTypeSignature (type) ?? default; + if (!typeSig.IsValid || typeSig.SimpleReference == null) { + throw new ArgumentException ($"Could not determine Java type corresponding to `{type.AssemblyQualifiedName}`.", nameof (targetType)); + } + JniObjectReference typeClass; + try { + typeClass = JniEnvironment.Types.FindClass (typeSig.SimpleReference); + } catch (Exception e) { + throw new ArgumentException ($"Could not find Java class `{typeSig.SimpleReference}`.", + nameof (targetType), + e); + } + + var handleClass = JniEnvironment.Types.GetObjectClass (new JniObjectReference (handle)); + if (!JniEnvironment.Types.IsAssignableFrom (handleClass, typeClass)) { + Logger.Log (LogLevel.Info, "*jonp*", $"# jonp: can't assign `{GetClassName(handleClass.Handle)}` to `{GetClassName(typeClass.Handle)}`"); + JniObjectReference.Dispose (ref handleClass); + JniObjectReference.Dispose (ref typeClass); + return null; + } IJavaPeerable? result = null; From c027902e58eb1424d7a9722ad0154113005971e5 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 5 Jul 2024 13:07:06 -0400 Subject: [PATCH 3/4] Update to dotnet/java-interop@18329a8c. --- external/Java.Interop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/Java.Interop b/external/Java.Interop index 31045b80bbc..18329a8c38a 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 31045b80bbc70efe9dc7ef7ace4862804d716b7f +Subproject commit 18329a8c38a186b0c41f084fd722515a4ab28a02 From a69782d58161304692970be60e6cec7d7afdfaef Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Mon, 8 Jul 2024 13:50:10 -0400 Subject: [PATCH 4/4] Bump to dotnet/java-interop/main@7a058c0e Fixes: https://github.com/dotnet/android/issues/9038 --- .gitmodules | 2 +- external/Java.Interop | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 00b83da1a59..ea5f83ceb43 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,7 +13,7 @@ [submodule "external/Java.Interop"] path = external/Java.Interop url = https://github.com/dotnet/java-interop - branch = dev/jonp/jonp-add-JavaAs + branch = main [submodule "external/libunwind"] path = external/libunwind url = https://github.com/libunwind/libunwind.git diff --git a/external/Java.Interop b/external/Java.Interop index 18329a8c38a..7a058c0ee50 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 18329a8c38a186b0c41f084fd722515a4ab28a02 +Subproject commit 7a058c0ee50d39dc5783d2b2770ea5e0f1001a56