Skip to content

Commit 525f755

Browse files
[Mono.Android] fix "replaceable" objects in ManagedValueManager (#10107)
Context: d3d3584 Context: dotnet/java-interop@d3d3a1b The following test was failing on NativeAOT as well as whenever we'd use `ManagedValueManager`: [Test] public void JnienvCreateInstance_RegistersMultipleInstances () { using (var adapter = new CreateInstance_OverrideAbsListView_Adapter (Application.Context)) { var intermediate = CreateInstance_OverrideAbsListView_Adapter.Intermediate; var registered = Java.Lang.Object.GetObject<CreateInstance_OverrideAbsListView_Adapter>(adapter.Handle, JniHandleOwnership.DoNotTransfer); Assert.AreNotSame (adapter, intermediate); // Passes Assert.AreSame (adapter, registered); // Fails! } } With the assertion: Expected: same as <com.xamarin.android.runtimetests.CreateInstance_OverrideAbsListView_Adapter{cbd0e5a V.ED.VC.. ......I. 0,0-0,0}> But was: <com.xamarin.android.runtimetests.CreateInstance_OverrideAbsListView_Adapter{cbd0e5a V.ED.VC.. ......I. 0,0-0,0}> The second assertion fails because `registered` is the same instance as `intermediate`. In this example, this is a code path where `intermediate` should be "replaced" with `adapter`. After lots of debugging, I found the problem are these lines in the `ManagedValueManager.AddPeer()` method: var o = PeekPeer (value.PeerReference); if (o != null) return; If we `PeekPeer()` in the middle of `AddPeer()` and a type is "replaceable", it would find an instance and not replace it! I did not find equivalent code in `AndroidValueManager.AddPeer()`, which is what is used in Mono & production today. This was also addressed in Java.Interop's `ManagedValueManager` by dotnet/java-interop@d3d3a1bf. This also solves a test failure in `Java.Interop-Tests`: Mono.Android.NET_Tests, Java.InteropTests.InvokeVirtualFromConstructorTests.CreateManagedInstanceFirst_WithNewObject / Release Error message Expected t and registered to be the same instance; t=20dfddd, registered=325d330 Expected: same as net.dot.jni.test.CallVirtualFromConstructorDerived@564f0f8 But was: net.dot.jni.test.CallVirtualFromConstructorDerived@564f0f8 Stack trace at Java.InteropTests.InvokeVirtualFromConstructorTests.CreateManagedInstanceFirst_WithNewObject() at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack, Void**, ObjectHandleOnStack, BOOL, ObjectHandleOnStack) at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack, Void**, ObjectHandleOnStack, BOOL, ObjectHandleOnStack) at System.RuntimeMethodHandle.InvokeMethod(Object, Void**, Signature, Boolean) at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args) at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object, BindingFlags)
1 parent 8a56052 commit 525f755

File tree

2 files changed

+0
-5
lines changed

2 files changed

+0
-5
lines changed

src/Mono.Android/Microsoft.Android.Runtime/ManagedValueManager.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ public override void AddPeer (IJavaPeerable value)
6767
var r = value.PeerReference;
6868
if (!r.IsValid)
6969
throw new ObjectDisposedException (value.GetType ().FullName);
70-
var o = PeekPeer (value.PeerReference);
71-
if (o != null)
72-
return;
7370

7471
if (r.Type != JniObjectReferenceType.Global) {
7572
value.SetPeerReference (r.NewGlobalRef ());

tests/Mono.Android-Tests/Mono.Android-Tests/Java.Lang/ObjectTest.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ static MethodInfo MakeGenericMethod (MethodInfo method, Type type) =>
6666
}
6767

6868
[Test]
69-
[Category ("CoreCLRIgnore")] //TODO: https://github.com/dotnet/android/issues/10069
70-
[Category ("NativeAOTIgnore")] //TODO: https://github.com/dotnet/android/issues/10079
7169
public void JnienvCreateInstance_RegistersMultipleInstances ()
7270
{
7371
using (var adapter = new CreateInstance_OverrideAbsListView_Adapter (Application.Context)) {

0 commit comments

Comments
 (0)