Skip to content

Commit bd793f1

Browse files
[Java.Interop.Tools.TypeNameMappings] fix ToJniName() (#1198)
Context: dotnet/android#8751 Context: 56b7eeb Context: 67c079c dotnet/android#8751 attempts to figure out how Java.Interop broke xamarin-android. That investigation eventually resulted in 67c079c, which allowed xamarin-android to *build* again, and uncovered a unit test failure. [`JnienvTest.NewObjectArrayWithNonJavaTypeAndEmptyArray()`][0]: [Test] public void NewObjectArrayWithNonJavaTypeAndEmptyArray () { //empty array gives the right type var array = JNIEnv.NewObjectArray<Type> (new Type [0]); … } started failing: 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 56b7eeb, we lost an important detail from the expression: // 56b7eeb^ if (!type.GetInterfaces ().Any (t => t.FullName == "Android.Runtime.IJavaObject")) … // 56b7eeb equivalent: if (type.GetInterfaces ().Any (t => t.FullName == "Java.Interop.IJavaPeerable")) … 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. [0]: https://github.com/xamarin/xamarin-android/blob/0665f449948c43675ec8706a5a2807b5d3f599f7/tests/Mono.Android-Tests/Java.Interop/JnienvTest.cs#L178-L186
1 parent 67c079c commit bd793f1

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ public static string ToJniName (Type type)
196196
// Trimming warnings are not enabled for netstandard2.0 in this project.
197197
static bool ShouldCheckSpecialExportJniType (Type type) =>
198198
#if NETSTANDARD2_0
199-
type.GetInterfaces ().Any (t => t.FullName == "Java.Interop.IJavaPeerable");
199+
!type.GetInterfaces ().Any (t => t.FullName == "Java.Interop.IJavaPeerable");
200200
#else
201-
IJavaPeerableType.Value.IsAssignableFrom (type);
201+
!IJavaPeerableType.Value.IsAssignableFrom (type);
202202
#endif
203203

204204
public static string ToJniName (string jniType, int rank)

tests/Java.Interop.Tools.JavaCallableWrappers-Tests/Java.Interop.Tools.JavaCallableWrappers/JavaNativeTypeManagerTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,14 @@ public void LowercaseWithAssemblyName ()
5555
Assert.AreEqual ("assembly_mscorlib.system", JavaNativeTypeManager.GetPackageName (typeof (string)));
5656
#endif // !NET
5757
}
58+
59+
[Test]
60+
[TestCase (typeof (string), "java/lang/String")]
61+
[TestCase (typeof (Type), "java/lang/Object")]
62+
public void ToJniName (Type type, string expected)
63+
{
64+
string actual = JavaNativeTypeManager.ToJniName (type);
65+
Assert.AreEqual (expected, actual);
66+
}
5867
}
5968
}

0 commit comments

Comments
 (0)