-
Notifications
You must be signed in to change notification settings - Fork 64
Include interfaces in type maps #824
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Java typemaps have never included interfaces because, till very
recently, they couldn't contain methods so they couldn't have been used
as method invocation targets. With the addition of DIM (Default
Interface Methods) to C# this is no longer true. Exclusion of
interfaces from typemaps can lead to errors similar to:
---- DEBUG ASSERTION FAILED ----
---- Assert Short Message ----
ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.App.Application+IActivityLifecycleCallbacks)).JniTypeName="" != "android/app/Application$ActivityLifecycleCallbacks"
---- Assert Long Message ----
at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) in System.Private.CoreLib.dll:token 0x6005586+0x0
at System.Diagnostics.Debug.Fail(String message, String detailMessage) in System.Private.CoreLib.dll:token 0x6005548+0x0
at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) in System.Private.CoreLib.dll:token 0x6005545+0x0
at System.Diagnostics.Debug.Assert(Boolean condition, String message) in System.Private.CoreLib.dll:token 0x6005544+0x0
at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) in Java.Interop.dll:token 0x600032e+0x0
at Java.Interop.JniPe
Process terminated due to "ManagedPeerType <=> JniTypeName Mismatch! javaVM.GetJniTypeInfoForType(typeof(Android.App.Application+IActivityLifecycleCallbacks)).JniTypeName="" != "android/app/Application$ActivityLifecycleCallbacks"
at System.Diagnostics.DebugProvider.Fail(String message, String detailMessage) in System.Private.CoreLib.dll:token 0x6005586+0x0
at System.Diagnostics.Debug.Fail(String message, String detailMessage) in System.Private.CoreLib.dll:token 0x6005548+0x0
at System.Diagnostics.Debug.Assert(Boolean condition, String message, String detailMessage) in System.Private.CoreLib.dll:token 0x6005545+0x0
at System.Diagnostics.Debug.Assert(Boolean condition, String message) in System.Private.CoreLib.dll:token 0x6005544+0x0
at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean checkManagedPeerType, Boolean isInterface) in Java.Interop.dll:token 0x600032e+0x0
at Java.Interop.JniPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean isInterface) in Java.Interop.dll:token 0x600032c+0x0
at Android.Runtime.XAPeerMembers..ctor(String jniPeerTypeName, Type managedPeerType, Boolean isInterface) in Mono.Android.dll:token 0x6017ed3+0x0
at Android.App.Application.IActivityLifecycleCallbacks..cctor() in Mono.Android.dll:token 0x6025027+0x0
at Android.Runtime.AndroidTypeManager.RegisterNativeMembers(JniType nativeClass, Type type, String methods) in Mono.Android.dll:token 0x6017c19+0x0
at Android.Runtime.JNIEnv.RegisterJniNatives(IntPtr typeName_ptr, Int32 typeName_len, IntPtr jniClass, IntPtr methods_ptr, Int32 methods_len) in Mono.Android.dll:token 0x6017d48+0x0
at Java.Interop.NativeMethods.java_interop_jnienv_alloc_object(IntPtr , IntPtr& , IntPtr ) in Java.Interop.dll:token 0x0+0x0
at Java.Interop.JniEnvironment.Object.AllocObject(JniObjectReference type) in Java.Interop.dll:token 0x6000563+0x0
at Java.Interop.JniType.AllocObject() in Java.Interop.dll:token 0x60003a1+0x0
at Java.Interop.JniPeerMembers.JniInstanceMethods.StartCreateInstance(String constructorSignature, Type declaringType, JniArgumentValue* parameters) in Java.Interop.dll:token 0x60005e5+0x0
at Java.Lang.Object..ctor() in Mono.Android.dll:token 0x601ea58+0x0
at Microsoft.Maui.MauiApplication.ActivityLifecycleCallbacks..ctor() in Microsoft.Maui.dll:token 0x60004ef+0x0
at Microsoft.Maui.MauiApplication`1[[HelloMaui.Startup, HelloMaui, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].OnCreate() in Microsoft.Maui.dll:token 0x6000114+0x0
at Android.App.Application.n_OnCreate(IntPtr jnienv, IntPtr native__this) in Mono.Android.dll:token 0x60153c7+0x0
at Android.Runtime.DynamicMethodNameCounter.1(IntPtr , IntPtr ) in Mono.Android.dll:token 0x0+0x0"
This is caused by the fact that a class (`MauiApplication.ActivityLifecycleCallbacks`
in this case) implements a Java interace (`IActivityLifecycleCallbacks`
here) but it does not implement all the interface memebers. In such
instance, the default interface methods will be called (if available).
Xamarin.Android pairs each Java interface with a class, called an
Invoker, which is used for actual invocation of the interface methods.
In the case of the above crash, however, the
`IActivityLifecycleCallbacksInvoker` class doesn't implement one of the
`IActivityLifecycleCallbacks` interface methods (`OnActivityPostCreated`)
which causes `Android.Runtime.AndroidTypeManager.RegisterNativeMembers`
to attempt to invoke the default method in
`IActivityLifecycleCallbacks`. This, in turn, leads to `XAPeerMembers`
attempting to map its owner's managed type (`IActivityLifecycleCallbacks`)
to its Java counterpart by using a typemap lookup. However, since
interfaces aren't present in typemaps, the lookup fails and we get the
above exception.
Fix the issue by including all interfaces implementing the
`Java.Interop.IJavaPeerable` interface in typemaps.
grendello
added a commit
to grendello/xamarin-android
that referenced
this pull request
Apr 21, 2021
Context: dotnet/java-interop#824 With `Java.Interop` Java type scanner now including Java interfaces in the returned set of types, we need to ignore interfaces when generating JCWs.
grendello
added a commit
to grendello/xamarin-android
that referenced
this pull request
Apr 21, 2021
Context: dotnet/java-interop#824 With `Java.Interop` Java type scanner now including Java interfaces in the returned set of types, we need to ignore interfaces when generating JCWs.
grendello
added a commit
to grendello/xamarin-android
that referenced
this pull request
Apr 22, 2021
Context: dotnet/java-interop#824 With `Java.Interop` Java type scanner now including Java interfaces in the returned set of types, we need to ignore interfaces when generating JCWs.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Java typemaps have never included interfaces because, till very
recently, they couldn't contain methods so they couldn't have been used
as method invocation targets. With the addition of DIM (Default
Interface Methods) to C# this is no longer true. Exclusion of
interfaces from typemaps can lead to errors similar to:
This is caused by the fact that a class (
MauiApplication.ActivityLifecycleCallbacksin this case) implements a Java interace (
IActivityLifecycleCallbackshere) but it does not implement all the interface memebers. In such
instance, the default interface methods will be called (if available).
Xamarin.Android pairs each Java interface with a class, called an
Invoker, which is used for actual invocation of the interface methods.
In the case of the above crash, however, the
IActivityLifecycleCallbacksInvokerclass doesn't implement one of theIActivityLifecycleCallbacksinterface methods (OnActivityPostCreated)which causes
Android.Runtime.AndroidTypeManager.RegisterNativeMembersto attempt to invoke the default method in
IActivityLifecycleCallbacks. This, in turn, leads toXAPeerMembersattempting to map its owner's managed type (
IActivityLifecycleCallbacks)to its Java counterpart by using a typemap lookup. However, since
interfaces aren't present in typemaps, the lookup fails and we get the
above exception.
Fix the issue by including all interfaces implementing the
Java.Interop.IJavaPeerableinterface in typemaps.