From 6048f6236974e44534ee1f17df3fd16e5a014b62 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Fri, 23 Feb 2024 14:53:41 -0600 Subject: [PATCH] [Java.Interop.Tools.TypeNameMappings] fix `ToJniName()` The following test in xamarin/xamarin-android: [Test] public void NewObjectArrayWithNonJavaTypeAndEmptyArray () { //empty array gives the right type var array = JNIEnv.NewObjectArray (new Type [0]); Throws with: Java.Lang.ClassNotFoundException : crc64d04135c992393d83.Type ----> Java.Lang.ClassNotFoundException : Didn't find class "crc64d04135c992393d83.Type" on path: DexPathList[[zip file "/data/app/Mono.Android.NET_Tests-VrfrXDHT2r32zDG95kFOiw==/base.apk", zip file "/data/app/Mono.Android.NET_Tests-VrfrXDHT2r32zDG95kFOiw==/split_config.x86_64.apk", zip file "/data/app/Mono.Android.NET_Tests-VrfrXDHT2r32zDG95kFOiw==/split_config.xxhdpi.apk"],nativeLibraryDirectories=[/data/app/Mono.Android.NET_Tests-VrfrXDHT2r32zDG95kFOiw==/lib/x86_64, /data/app/Mono.Android.NET_Tests-VrfrXDHT2r32zDG95kFOiw==/base.apk!/lib/x86_64, /data/app/Mono.Android.NET_Tests-VrfrXDHT2r32zDG95kFOiw==/split_config.x86_64.apk!/lib/x86_64, /data/app/Mono.Android.NET_Tests-VrfrXDHT2r32zDG95kFOiw==/split_config.xxhdpi.apk!/lib/x86_64, /system/lib64, /system/product/lib64]] It turns out, this type is completely wrong? It should be looking for `java/lang/Object` instead? In 56b7eeb7, we lost an important detail from the expression: if (!type.GetInterfaces ().Any (t => t.FullName == "Android.Runtime.IJavaObject")) We are missing the `!` !!! I was able to reproduce this behavior in a test: [Test] [TestCase (typeof (System.Type), "java/lang/Object")] public void ToJniName (Type type, string expected) { string actual = JavaNativeTypeManager.ToJniName (type); Assert.AreEqual (expected, actual); } Where `ToJniName()` was returning `crc64d04135c992393d83/Type` instead of `java/lang/Object`! After fixing the problem, the test passes. --- .../JavaNativeTypeManager.cs | 4 ++-- .../JavaNativeTypeManagerTests.cs | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs b/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs index 9d81e3804..17e895720 100644 --- a/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs +++ b/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs @@ -196,9 +196,9 @@ public static string ToJniName (Type type) // Trimming warnings are not enabled for netstandard2.0 in this project. static bool ShouldCheckSpecialExportJniType (Type type) => #if NETSTANDARD2_0 - type.GetInterfaces ().Any (t => t.FullName == "Java.Interop.IJavaPeerable"); + !type.GetInterfaces ().Any (t => t.FullName == "Java.Interop.IJavaPeerable"); #else - IJavaPeerableType.Value.IsAssignableFrom (type); + !IJavaPeerableType.Value.IsAssignableFrom (type); #endif public static string ToJniName (string jniType, int rank) diff --git a/tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers/JavaNativeTypeManagerTests.cs b/tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers/JavaNativeTypeManagerTests.cs index a86ff05f3..2c8e7b920 100644 --- a/tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers/JavaNativeTypeManagerTests.cs +++ b/tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers/JavaNativeTypeManagerTests.cs @@ -55,5 +55,14 @@ public void LowercaseWithAssemblyName () Assert.AreEqual ("assembly_mscorlib.system", JavaNativeTypeManager.GetPackageName (typeof (string))); #endif // !NET } + + [Test] + [TestCase (typeof (string), "java/lang/String")] + [TestCase (typeof (Type), "java/lang/Object")] + public void ToJniName (Type type, string expected) + { + string actual = JavaNativeTypeManager.ToJniName (type); + Assert.AreEqual (expected, actual); + } } }