Commit 75354b9
authored
[Java.Interop] Dispose, *then* Remove (#708)
Fixes: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1193891
A bug was found in Xamarin.Android 11.1.0.2, candidate for
Visual Studio 16.8 Preview 3:
1. Create a new "Shell Forms App"
2. Build & Run the app
3. Tap the "Browse" button.
Expected results: it works!
Actual results: A rather abrupt crash:
Unhandled Exception:
System.NotSupportedException: Unable to activate instance of type Xamarin.Forms.Platform.Android.PageRenderer from native handle 0x69 (key_handle 0x33efaa1). ---> System.MissingMethodException: No constructor found for Xamarin.Forms.Platform.Android.PageRenderer::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership) ---> Java.Interop.JavaLocationException: Exception of type 'Java.Interop.JavaLocationException' was thrown.
--- End of inner exception stack trace ---
at Java.Interop.TypeManager.CreateProxy (System.Type type, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer)
at Java.Interop.TypeManager.CreateInstance (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type targetType)
--- End of inner exception stack trace ---
at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.64(intptr,intptr)
at (wrapper native-to-managed) Android.Runtime.DynamicMethodNameCounter.64(intptr,intptr)
The crash was caused by commit 007b35b, which changed
`JniRuntime.JniValueManager.DisposePeer()` semantics from:
value.Disposed ();
RemovePeer (value);
and reversed this to:
RemovePeer (value);
value.Disposed ();
(Why this reversal? Unmentioned in 007b35b -- doh! -- but as
@jonpryor is the one who did this, "it seemed like a good idea
at the time!")
(Very clearly, this wasn't a good idea.)
The crash was caused by commit 007b35b interacting with Xamarin.Forms'
[`VisualElementPackager.Dispose(bool)`][0], which can call back into
Java code, potentially causing `this` to need to be returned.
When `RemovePeer()` is done *first*, as was done in 007b35b, then
there may be no available instance to return, causing the
`NotSupportedException` to be thrown.
The new `JavaObjectTest.DisposeAccessesThis()` test and associated
`Java.InteropTests.GetThis` type & Java peer trigger this scenario.
Without the fix, `DisposeAccessesThis()` fails with:
System.NotSupportedException : Could not find an appropriate constructable wrapper type for Java type 'com/xamarin/interop/GetThis', targetType='Java.InteropTests.GetThis'.
at Java.Interop.JniRuntime+JniValueManager.CreatePeer (Java.Interop.JniObjectReference& reference, Java.Interop.JniObjectReferenceOptions transfer, System.Type targetType)
at Java.Interop.JavaPeerableValueMarshaler.CreateGenericValue (Java.Interop.JniObjectReference& reference, Java.Interop.JniObjectReferenceOptions options, System.Type targetType)
at Java.Interop.JniRuntime+JniValueManager.GetValue[T] (Java.Interop.JniObjectReference& reference, Java.Interop.JniObjectReferenceOptions options, System.Type targetType)
at Java.InteropTests.GetThis.get_This ()
at Java.InteropTests.GetThis.Dispose (System.Boolean disposing)
at Java.Interop.JavaObject.Java.Interop.IJavaPeerable.Disposed ()
at Java.Interop.JniRuntime+JniValueManager.DisposePeer (Java.Interop.IJavaPeerable value)
at Java.Interop.JavaObject.Dispose ()
demonstrating how `RemovePeer(value)` *must not* happen before
`value.Disposed()`.
[0]: https://github.com/xamarin/Xamarin.Forms/blob/17881ec93d6b3fb0ee5e1a2be46d7eeadef23529/Xamarin.Forms.Platform.Android/VisualElementPackager.cs#L65-L1081 parent 8ea0bb2 commit 75354b9
File tree
5 files changed
+99
-2
lines changed- src/Java.Interop/Java.Interop
- tests/Java.Interop-Tests
- Java.Interop
- java/com/xamarin/interop
5 files changed
+99
-2
lines changedLines changed: 1 addition & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
149 | | - | |
150 | | - | |
151 | 149 | | |
| 150 | + | |
152 | 151 | | |
153 | 152 | | |
154 | 153 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| 43 | + | |
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
196 | 204 | | |
197 | 205 | | |
198 | 206 | | |
| |||
Lines changed: 42 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
0 commit comments