-
Notifications
You must be signed in to change notification settings - Fork 531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[.NET 6] Debug build of Java.Interop.dll crashes Xamarin.Forms applications #5409
Labels
Area: App+Library Build
Issues when building Library projects or Application projects.
Area: App Runtime
Issues in `libmonodroid.so`.
bug
Component does not function as intended.
Milestone
Comments
jonathanpeppers
added
Area: App+Library Build
Issues when building Library projects or Application projects.
Area: App Runtime
Issues in `libmonodroid.so`.
labels
Dec 14, 2020
grendello
added a commit
to grendello/xamarin-android
that referenced
this issue
Jan 5, 2021
Fixes: dotnet#5409 Context: a017561 Context: bb55bb0 This is another commit in the series of properly handling the N:1 type mapping from Java to Managed types. a017561 implemented most of the handling properly, bb55bb0 fixed it up for generic types but neither of the two commits accounted for the situation when a Managed type map is requested that points back to a duplicate Java type. In fact, such Managed types were removed from the typemap unless they were the type pointed to from the Java duplicate. This meant that, effectively, all the `*Invoker` classes were not part of the mapping, leading to this error for Debug builds: app_process32: ---- DEBUG ASSERTION FAILED ---- app_process32: ---- Assert Short Message ---- app_process32: ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.Views.LayoutInflaterInvoker)).JniTypeName="" != "android/view/LayoutInflater" app_process32: ---- Assert Long Message ---- app_process32: app_process32: at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Fail(String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Assert(Boolean condition, String message) app_process32: at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) app_process32: at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) app_process32: at Android.Runtime.XAPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) app_process32: at Android.Views.LayoutInflaterInvoker..cctor() app_process32: at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstruct : CLR: Managed code called FailFast, saying "ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.Views.LayoutInflaterInvoker)).JniTypeName="" != "android/view/LayoutInflater" : at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) : at System.Diagnostics.Debug.Fail(String message, String detailMessage) : at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) : at System.Diagnostics.Debug.Assert(Boolean condition, String message) : at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) : at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) : at Android.Runtime.XAPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) : at Android.Views.LayoutInflaterInvoker..cctor() This commit modifies the mapping code to make sure that all duplicate Java types point to the **first** Managed type but that all the Managed types point back to their original Java type.
jonpryor
pushed a commit
that referenced
this issue
Jan 7, 2021
…5459) Fixes: #5409 Context: a017561 Context: bb55bb0 Yet Another Java :: Managed Type Aliasing Issue. Type aliasing occurs when multiple managed types bind the same Java type. One common scenario for this is for `abstract` classes: // Java: public abstract class LayoutInflater { // … } // C# Binding [Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)] public abstract class LayoutInflater : Java.Lang.Object { static readonly JniPeerMembers _members = new XAPeerMembers ("android/view/LayoutInflater", typeof (LayoutInflater)); } // Used at runtime [Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)] internal partial class LayoutInflaterInvoker : LayoutInflater { static readonly JniPeerMembers _members = new XAPeerMembers ("android/view/LayoutInflater", typeof (LayoutInflaterInvoker)); } Both the C# `LayoutInflater` and `LayoutInflaterInvoker` types *alias* the Java `LayoutInflater` type. In a *Debug* configuration build, the mappings between the Java types and Managed types is held within a per-assembly mapping (7117414), and because of a017561 there is no explicit managed entry for `LayoutInflaterInvoker`: DebugTypemap = { .java_to_managed = { { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater }, .managed_to_java = { { "Android.Views.LayoutInflater", 0 }, // C# LayoutInflater -> Java LayoutInflater { "Android.Views.LayoutInflater", 0 }, // C# LayoutInflaterInvoker -> Java LayoutInflater }, } At *runtime* when the `LayoutInflaterInvoker` static constructor is executed, we hit an [assert in the `JniPeerMembers` constructor][0]: app_process32: ---- DEBUG ASSERTION FAILED ---- app_process32: ---- Assert Short Message ---- app_process32: ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.Views.LayoutInflaterInvoker)).JniTypeName="" != "android/view/LayoutInflater" app_process32: ---- Assert Long Message ---- app_process32: app_process32: at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Fail(String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Assert(Boolean condition, String message) app_process32: at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) app_process32: at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) app_process32: at Android.Runtime.XAPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) app_process32: at Android.Views.LayoutInflaterInvoker..cctor() app_process32: at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstruct : CLR: Managed code called FailFast, saying "ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.Views.LayoutInflaterInvoker)).JniTypeName="" != "android/view/LayoutInflater" : at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) : at System.Diagnostics.Debug.Fail(String message, String detailMessage) : at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) : at System.Diagnostics.Debug.Assert(Boolean condition, String message) : at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) : at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) : at Android.Runtime.XAPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) : at Android.Views.LayoutInflaterInvoker..cctor() The cause of the assertion failure is because the `.managed_to_java` table doesn't contain an entry for `LayoutInflaterInvoker`. The fix is to modify a017561 behavior and *retain* the `*Invoker` types in the `.managed_to_java` table: DebugTypemap = { .java_to_managed = { { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater }, .managed_to_java = { { "Android.Views.LayoutInflater", 0 }, // C# LayoutInflater -> Java LayoutInflater { "Android.Views.LayoutInflaterInvoker", 0 }, // C# LayoutInflaterInvoker -> Java LayoutInflater }, } This ensures that we can appropriately obtain a Java type name for the `LayoutInflaterInvoker` type, fixing the assert. [0]: https://github.com/xamarin/java.interop/blob/3894cd76f71f618949c8542f0edd95762e22881f/src/Java.Interop/Java.Interop/JniPeerMembers.cs#L29
jonpryor
pushed a commit
that referenced
this issue
Jan 15, 2021
…5459) Fixes: #5409 Context: a017561 Context: bb55bb0 Yet Another Java :: Managed Type Aliasing Issue. Type aliasing occurs when multiple managed types bind the same Java type. One common scenario for this is for `abstract` classes: // Java: public abstract class LayoutInflater { // … } // C# Binding [Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)] public abstract class LayoutInflater : Java.Lang.Object { static readonly JniPeerMembers _members = new XAPeerMembers ("android/view/LayoutInflater", typeof (LayoutInflater)); } // Used at runtime [Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)] internal partial class LayoutInflaterInvoker : LayoutInflater { static readonly JniPeerMembers _members = new XAPeerMembers ("android/view/LayoutInflater", typeof (LayoutInflaterInvoker)); } Both the C# `LayoutInflater` and `LayoutInflaterInvoker` types *alias* the Java `LayoutInflater` type. In a *Debug* configuration build, the mappings between the Java types and Managed types is held within a per-assembly mapping (7117414), and because of a017561 there is no explicit managed entry for `LayoutInflaterInvoker`: DebugTypemap = { .java_to_managed = { { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater }, .managed_to_java = { { "Android.Views.LayoutInflater", 0 }, // C# LayoutInflater -> Java LayoutInflater { "Android.Views.LayoutInflater", 0 }, // C# LayoutInflaterInvoker -> Java LayoutInflater }, } At *runtime* when the `LayoutInflaterInvoker` static constructor is executed, we hit an [assert in the `JniPeerMembers` constructor][0]: app_process32: ---- DEBUG ASSERTION FAILED ---- app_process32: ---- Assert Short Message ---- app_process32: ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.Views.LayoutInflaterInvoker)).JniTypeName="" != "android/view/LayoutInflater" app_process32: ---- Assert Long Message ---- app_process32: app_process32: at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Fail(String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) app_process32: at System.Diagnostics.Debug.Assert(Boolean condition, String message) app_process32: at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) app_process32: at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) app_process32: at Android.Runtime.XAPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) app_process32: at Android.Views.LayoutInflaterInvoker..cctor() app_process32: at System.Reflection.RuntimeConstructorInfo.InternalInvoke(RuntimeConstruct : CLR: Managed code called FailFast, saying "ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.Views.LayoutInflaterInvoker)).JniTypeName="" != "android/view/LayoutInflater" : at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) : at System.Diagnostics.Debug.Fail(String message, String detailMessage) : at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) : at System.Diagnostics.Debug.Assert(Boolean condition, String message) : at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) : at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) : at Android.Runtime.XAPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType) : at Android.Views.LayoutInflaterInvoker..cctor() The cause of the assertion failure is because the `.managed_to_java` table doesn't contain an entry for `LayoutInflaterInvoker`. The fix is to modify a017561 behavior and *retain* the `*Invoker` types in the `.managed_to_java` table: DebugTypemap = { .java_to_managed = { { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater { "android/view/LayoutInflater", 0 }, // Java LayoutInflater -> C# LayoutInflater }, .managed_to_java = { { "Android.Views.LayoutInflater", 0 }, // C# LayoutInflater -> Java LayoutInflater { "Android.Views.LayoutInflaterInvoker", 0 }, // C# LayoutInflaterInvoker -> Java LayoutInflater }, } This ensures that we can appropriately obtain a Java type name for the `LayoutInflaterInvoker` type, fixing the assert. [0]: https://github.com/xamarin/java.interop/blob/3894cd76f71f618949c8542f0edd95762e22881f/src/Java.Interop/Java.Interop/JniPeerMembers.cs#L29
ghost
locked as resolved and limited conversation to collaborators
Jun 3, 2022
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
Area: App+Library Build
Issues when building Library projects or Application projects.
Area: App Runtime
Issues in `libmonodroid.so`.
bug
Component does not function as intended.
Steps to Reproduce
Build a Debug build of xamarin-android locally with
msbuild Xamarin.Android.sln -t:PackDotNet
ormake pack-dotnet
Build this Xamarin.Forms sample:
~\android-toolchain\dotnet\dotnet build .\HelloForms\HelloForms.csproj -t:Run -p:TargetFramework=net6.0-android
You may need to add an entry to
NuGet.config
, full path to:Crashes with:
This works if you have a
Release
build ofJava.Interop.dll
because this assertion is stripped away:https://github.com/xamarin/java.interop/blob/2f62ffd4367870802f146c7957a94839daf1b86d/src/Java.Interop/Java.Interop/JniPeerMembers.cs#L27-L34
We think there must be some issue with type maps in this project?
We probably won't be able to look into this until January, so I thought I'd post this so we don't forget.
The text was updated successfully, but these errors were encountered: