-
Notifications
You must be signed in to change notification settings - Fork 555
[CoreCLR] Override GetInvokerTypeCore in AndroidTypeManager #9978
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
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
Oddly, the macOS build failed in
No idea what's up with that. I've restarted that build. |
@jonpryor I think the other PR triggered a build for the same commit hash, this one is: |
jonathanpeppers
pushed a commit
that referenced
this pull request
Mar 28, 2025
…9978) Context: e347cd3 Context: #9962 Context: dotnet/java-interop@dd3c1d0 CoreCLR + `dotnet new maui -sc` (#9962) crashes: E AndroidRuntime: FATAL EXCEPTION: main E AndroidRuntime: Process: com.companyname.testmaui, PID: 25497 E AndroidRuntime: android.runtime.JavaProxyThrowable: [System.≈]: Acc_CreateAbstEx, Android.Views.LayoutInflater E AndroidRuntime: at System.Reflection.RuntimeConstructorInfo.CheckCanCreateInstance + 0x3c(Unknown Source) E AndroidRuntime: at System.Reflection.RuntimeConstructorInfo.ThrowNoInvokeException + 0x0(Unknown Source) E AndroidRuntime: at System.Reflection.RuntimeConstructorInfo.Invoke + 0xe(Unknown Source) E AndroidRuntime: at System.Reflection.ConstructorInfo.Invoke + 0x0(Unknown Source) E AndroidRuntime: at Microsoft.Android.Runtime.ManagedValueManager.TryCreatePeer + 0x3b(Unknown Source) E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.TryCreatePeerInstance + 0x19(Unknown Source) E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.CreatePeerInstance + 0x5a(Unknown Source) E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.CreatePeer + 0x150(Unknown Source) E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.GetPeer + 0x169(Unknown Source) E AndroidRuntime: at Java.Lang.Object.GetObject + 0x1d(Unknown Source) E AndroidRuntime: at Java.Lang.Object._GetObject + 0x19(Unknown Source) E AndroidRuntime: at Java.Lang.Object.GetObject + 0x1(Unknown Source) E AndroidRuntime: at Android.Views.LayoutInflater.From + 0x3f(Unknown Source) E AndroidRuntime: at Microsoft.Maui.Platform.MauiContextExtensions.GetLayoutInflater + 0x2b(Unknown Source) `AndroidTypeManager` didn't override the `JniRuntime.JniTypeManager.GetInvokerTypeCore()` method (dotnet/java-interop@dd3c1d05) and the base implementation of this method in `JniTypeManager` only looks at `JniTypeSignatureAttribute` to find the "invoker" type. .NET for Android bindings don't use `JniTypeSignatureAttribute`, they use `RegisterAttribute`; for example, consider the abstract `Android.Views.LayoutInflater` class: [Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)] partial class LayoutInflater : Java.Lang.Object { } [global::Android.Runtime.Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)] internal partial class LayoutInflaterInvoker : LayoutInflater { } The default `JniRuntime.JniTypeManager.GetInvokerType()` behavior will not work with .NET for Android bindings. This has historically been fine because `AndroidValueManager.CreatePeer()` / `TypeManager.CreateInstance()` would use `JavaObjectExtensions.GetInvokerType()` to obtain the `Invoker` type via "pattern-based Reflection", appending `Invoker` to the abstract type name to obtain a non-abstract constructable type. That historical behavior changed with e347cd3: CoreCLR doesn't use `AndroidValueManager`, but instead now uses `ManagedValueManager`, which *doesn't* call `TypeManager.CreateInstance()` or `JavaObjectExtensions.GetInvokerType()`. It instead relies on `JniRuntime.JniTypeManager.GetInvokerType()`, and as that was not overridden by `AndroidTypeManager`, the invoker for `LayoutInflater` could not be found, resulting in a `MemberAccessException` as we attempt to invoke the constructor on the *abstract* `LayoutInflater` type itself! [^0]. Add an `AndroidTypeManager.GetInvokerTypeCore()` method override which calls `JavaObjectExtensions.GetInvokerType` when needed to keep backwards compatibility. [^0]: The "complete" exception message would be: Cannot create an instance of Android.Views.LayoutInflater because it is an abstract class.
grendello
added a commit
that referenced
this pull request
Mar 28, 2025
* main: Bump to dotnet/java-interop@7b45b166 (#9982) [Mono.Android] Add AndroidTypeManager.GetInvokerTypeCore() override (#9978)
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.
This is a follow-up to #9973
Replaces #9977 (CI was failing due to long branch name)
This PR fixes the following crash at the startup of
dotnet new maui -sc
when theAndroidTypeManager
is used:AndroidTypeManager
didn't override theGetInvokerTypeCore
method and the base implementation of this method inJniTypeManager
only looks atJniTypeSignatureAttribute
to find the invoker type.LayoutInflater
doesn't have this attribute and it relies on the logic inJavaObjectExtensions.GetInvokerType
. This method will look for the invoker based on a naming convention by adding theInvoker
suffix to the original type name.This PR adds an override of
GetInvokerTypeCore
which callsJavaObjectExtensions.GetInvokerType
when needed to keep backwards compatibility.