Skip to content

[Mono.Android] Java.Lang.Object.GetObject<T>() implementation - #9728

Merged
jonpryor merged 1 commit into
mainfrom
dev/peppers/object/getobject
Jan 30, 2025
Merged

[Mono.Android] Java.Lang.Object.GetObject<T>() implementation#9728
jonpryor merged 1 commit into
mainfrom
dev/peppers/object/getobject

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Context: #9630
Context: dotnet/java-interop#1295

As an alternative to #9630...

For NativeAOT support, implement Java.Lang.Object.GetObject() using the new JniRuntime.JniValueManager.GetPeer() method.

This also cleans up a few things if Java.Lang.Object introduces an internal DynamicallyAccessedMemberTypes Constructors field.

Context: #9630
Context: dotnet/java-interop#1295
As an alternative to #9630...
For NativeAOT support, implement `Java.Lang.Object.GetObject()` using
the new `JniRuntime.JniValueManager.GetPeer()` method.
This also cleans up a few things if `Java.Lang.Object` introduces an
internal `DynamicallyAccessedMemberTypes Constructors` field.
@jonathanpeppers
jonathanpeppersforce-pushed the dev/peppers/object/getobject branch from 5a208fb to 310dee1CompareJanuary 30, 2025 16:20
jonpryor added a commit that referenced this pull request Jan 30, 2025
This reverts commit f3c122e.
This doens't build, because d3cde47 turns all warnings into errors,
and this commit introduces a warning.
PR #9728 is the proper fix.
@jonathanpeppers
jonathanpeppers marked this pull request as ready for review January 30, 2025 17:55
@jonpryor

jonpryor commented Jan 30, 2025

Copy link
Copy Markdown
Contributor

Draft commit message:

Context: https://github.com/dotnet/android/pull/9630
Context: https://github.com/dotnet/android/pull/9716
Context: https://github.com/dotnet/java-interop/commit/e288589d92afc9edd9070638ebed72f67e310117
Context: @jonathanpeppers attempted to prototype MAUI startup in a NativeAOT
environment, which promptly crashes similar to:
E AndroidRuntime: net.dot.jni.internal.JavaProxyThrowable: System.DllNotFoundException: DllNotFound_Linux, xa-internal-api, E AndroidRuntime: dlopen failed: library "xa-internal-api" not foundE AndroidRuntime: dlopen failed: library "libxa-internal-api" not foundE AndroidRuntime: E AndroidRuntime: at System.Runtime.InteropServices.NativeLibrary.LoadLibErrorTracker.Throw(String) + 0x47E AndroidRuntime: at Internal.Runtime.CompilerHelpers.InteropHelpers.FixupModuleCell(InteropHelpers.ModuleFixupCell*) + 0xe2E AndroidRuntime: at Internal.Runtime.CompilerHelpers.InteropHelpers.ResolvePInvokeSlow(InteropHelpers.MethodFixupCell*) + 0x35E AndroidRuntime: at Android.Runtime.RuntimeNativeMethods.monodroid_TypeManager_get_java_class_name(IntPtr) + 0x22E AndroidRuntime: at Java.Interop.TypeManager.GetClassName(IntPtr) + 0xeE AndroidRuntime: at Java.Interop.TypeManager.CreateInstance(IntPtr, JniHandleOwnership, Type) + 0x69E AndroidRuntime: at Java.Lang.Object._GetObject[T](IntPtr, JniHandleOwnership) + 0x4eE AndroidRuntime: at Android.App.Application.n_OnCreate(IntPtr jnienv, IntPtr native__this) + 0x89E AndroidRuntime: at my.MainApplication.n_onCreate(Native Method)E AndroidRuntime: at my.MainApplication.onCreate(MainApplication.java:24)E AndroidRuntime: at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1182)E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6460)E AndroidRuntime: at android.app.ActivityThread.access$1300(ActivityThread.java:219)E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:107)E AndroidRuntime: at android.os.Looper.loop(Looper.java:214)E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7356)E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
because:
1. MAUI apps provide an `Android.App.Application` sublass, and
2.[`Application` is "special"][0], and
3. When `Java.Lang.Object.GetObject<T>()` is hit for an instance
which doesn't already have an instance mapping -- i.e.
`Object.PeekObject()` returns `null` -- then we'd hit
`TypeManager.CreateInstance()`, which is a codepath full of
P/Invokes, and P/Invokes don't currently work on NativeAOT [^1].
The solution is to partially resuscitate PR #9630, but this time have
`Java.Lang.Object.GetObject<T>()` call
`Java.Interop.JniRuntime.JniValueManager.GetPeer()` instead of
`Java.Interop.JniRuntime.JniValueManager.GetValue()`; see also
dotnet/java-interop@e288589d.
This allows `Application` subclasses to be used (along with other
build system changes present in #9716).
This also cleans up a few things if `Java.Lang.Object` introduces an
internal `DynamicallyAccessedMemberTypes Constructors` field.
[0]: https://learn.microsoft.com/en-us/previous-versions/xamarin/android/internals/architecture#java-activation[^1]: It's *not* that NativeAOT doesn't support P/Invokes; it does.
The problem is that for a P/Invoke to work, we need to know the
name of the native library we're P/Invoking into, and our
NativeAOT sample environment doesn't include any `.so` files
other than the one for the app, i.e. whatever we'd P/Invoke
into doesn't exist.

@jonpryor
jonpryor merged commit f800c1a into mainJan 30, 2025
@jonpryor
jonpryor deleted the dev/peppers/object/getobject branch January 30, 2025 19:02
grendello added a commit that referenced this pull request Jan 31, 2025
* main:
[ci] Remove references to sdk-insertions (#9731)
`$(AndroidPackVersionSuffix)`=preview.2 (#9733)
[Mono.Android] Java.Lang.Object.GetObject<T>() implementation (#9728)
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Mar 2, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jonathanpeppers@jonpryor