Skip to content
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

Starting in Xamarin.Android 10.3, "System.MemberAccessException: Cannot create an instance of ... `1[T]" in Debug configuration when using certain APIs that have both generic and non-generic versions #4809

Closed
brendanzagaeski opened this issue Jun 11, 2020 · 6 comments · Fixed by #4845
Assignees
Labels
Area: App Runtime Issues in `libmonodroid.so`. regression

Comments

@brendanzagaeski
Copy link
Contributor

Context: #4596
Context: #4660

For this particular test case, the issue only occurs when using the shared runtime or when the managed linker is disabled.

Partial workaround

  1. Disable Use Shared Runtime under the Android Options section of the Visual Studio project property pages for the project.
  2. Set the Linking setting to Sdk Assemblies Only.
  3. If deploying to an emulator, click the Advanced button and add the appropriate x86 or x86_64 item under Supported architectures.

Steps to reproduce

  1. Download and unzip the attached test case.
  2. Ensure that a hardware device is attached and that adb is running.
  3. msbuild -restore -p:Configuration=Debug -t:Install AndroidApp1\AndroidApp1.csproj
    
  4. Launch the app by tapping the app icon on the target device.

Test case: ArrayAdapterApp1.zip

Expected behavior

When built and deployed with Xamarin.Android 10.2, the application launches successfully and displays Hello World! in the center of the view.

Actual behavior

When built and deployed with Xamarin.Android 10.3, the application exits during launch:

System.MemberAccessException: Cannot create an instance of Android.Widget.ArrayAdapter`1[T] because Type.ContainsGenericParameters is true.
  at System.Reflection.RuntimeConstructorInfo.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in <d772a4bbe86c4dc5b425d8ca91786b91>:0 
  at System.Reflection.RuntimeConstructorInfo.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0 
  at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0 
  at Java.Interop.TypeManager.CreateProxy (System.Type type, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x0001b] in <43cddc76fe22432dbdbcea2397b6fcd7>:0 
  at Java.Interop.TypeManager.CreateInstance (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type targetType) [0x00111] in <43cddc76fe22432dbdbcea2397b6fcd7>:0 
  at Java.Lang.Object.GetObject (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type type) [0x00023] in <43cddc76fe22432dbdbcea2397b6fcd7>:0 
  at Java.Lang.Object._GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00017] in <43cddc76fe22432dbdbcea2397b6fcd7>:0 
  at Java.Lang.Object.GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <43cddc76fe22432dbdbcea2397b6fcd7>:0 
  at Android.Widget.ArrayAdapter.CreateFromResource (Android.Content.Context context, System.Int32 textArrayResId, System.Int32 textViewResId) [0x0006d] in <43cddc76fe22432dbdbcea2397b6fcd7>:0 
  at AndroidApp1.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00031] in <51ce4ed05744482eb8a8079a399a17d2>:0 
  at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <43cddc76fe22432dbdbcea2397b6fcd7>:0 
  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.3(intptr,intptr,intptr)

Version information

  • Xamarin.Android SDK 10.3.1.4 (d16-6/3a10de9)
    • Mono: 165f4b0
    • Java.Interop: xamarin/java.interop/d16-6@2cab35c

The issue also occurs with Visual Studio 2019 version 16.7 Preview 2:

  • Xamarin.Android SDK 10.3.99.259 (d16-7/feabf52)
    • Mono: 075c3f0
    • Java.Interop: xamarin/java.interop/d16-7@d6024f1
@brendanzagaeski
Copy link
Contributor Author

I have only been able to reproduce this in the Debug configuration (with the debug libmonodroid.so), so it seems the fixes for Release configuration builds (with the release libmonodroid.so) are still verified.

@brendanzagaeski brendanzagaeski added the Area: App Runtime Issues in `libmonodroid.so`. label Jun 12, 2020
@brendanzagaeski brendanzagaeski changed the title Starting in Xamarin.Android 10.3, "System.MemberAccessException: Cannot create an instance of ... `1[T]" when using certain APIs that have both generic and non-generic versions Starting in Xamarin.Android 10.3, "System.MemberAccessException: Cannot create an instance of ... `1[T]" in Debug configuration when using certain APIs that have both generic and non-generic versions Jun 12, 2020
@grendello
Copy link
Contributor

log-new-fastdev.txt
log-regular-fastdev.txt

I can't reproduce the issue with XA/master :( Attached you can find logcats from two cold-start (no previous version of the application on device exists, no shared runtime installed) sessions for both the "old" and the "new" (Dexes) fastdev deployment models (the former puts typemaps in libxamarin-app.so the latter in *.typemap files uploaded to the override directory). The app was tested on Pixel 3 XL running Android 10.

@brendanzagaeski
Copy link
Contributor Author

brendanzagaeski commented Jun 20, 2020

Ah, yep. I can't reproduce either using a locally built v9.0/Mono.Android.dll from master, but a way to get the issue back is to replace the assembly with the version from CI.

Steps I followed:

  1. Open the latest status on https://github.com/xamarin/xamarin-android/commits/.

  2. Open the Details for the JENKINS-SIGN step.

  3. Download the .vsix.

  4. Extract v9.0\Mono.Android.dll:

    & "C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\Common7\IDE\Extensions\Xamarin.VisualStudio\7-Zip\7z.exe" x -r C:\Temp\Xamarin.Android.Sdk-10.4.100.108.vsix '$ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v9.0\Mono.Android.dll'
  5. Copy it into the local build:

    Copy-Item '$ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v9.0\Mono.Android.dll' C:\Source\xamarin-android\bin\Debug\lib\xamarin.android\xbuild-frameworks\MonoAndroid\v9.0\Mono.Android.dll
  6. Rebuild and redeploy the app:

    & ".\bin\Debug\bin\xabuild.exe" -restore "-t:Clean,Install" -p:Configuration=Debug -p:AndroidUseSharedRuntime=false -p:EmbedAssembliesIntoApk=true C:\Temp\ArrayAdapterApp1\AndroidApp1\AndroidApp1.csproj

    (At least one version of the issue occurs without the shared runtime, so I used that approach for this test.)

@grendello
Copy link
Contributor

grendello commented Jun 22, 2020

@brendanzagaeski It appears you don't need to get Mono.Android.dll from the vsix to reproduce. What you need is a local Release Xamarin.Android build (i.e. a make CONFIGURATION=Release one) and only the v9.0 version of the assembly causes the exception to be thrown (I tested framework versions down to v7.1, the sample app fails to build for anything older)

grendello added a commit to grendello/xamarin-android that referenced this issue Jun 22, 2020
Fixes: dotnet#4809
Context: 7117414
Context: a017561

Part of the a017561 commit dealt with mappings from certain Java types
which point to the same Managed type by making sure that they all refer
to the same type definition and managed type name.  However, in doing so
it failed to synchronize the property which indicates that we are
dealing with an interface or generic type, in which case such a type
should be ignored by the type mapping code in the runtime.

In this particular case, the issue was with the `ArrayAdapter` type
which has both a generic and non-generic definitions and it so happens
that the *first* type in `Mono.Android` assembly is the generic one,
thus it, and its duplicate, should be ignored but due to the failure to
synchronize the `SkipInJavaToManaged` property, the second instance of
the type was not skipped on the runtime, resulting in the following
exception:

    System.MemberAccessException: Cannot create an instance of Android.Widget.ArrayAdapter`1[T] because Type.ContainsGenericParameters is true.
      at System.Reflection.RuntimeConstructorInfo.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
      at System.Reflection.RuntimeConstructorInfo.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
      at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
      at Java.Interop.TypeManager.CreateProxy (System.Type type, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x0001b] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
      at Java.Interop.TypeManager.CreateInstance (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type targetType) [0x00111] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
      at Java.Lang.Object.GetObject (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type type) [0x00023] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
      at Java.Lang.Object._GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00017] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
      at Java.Lang.Object.GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
      at Android.Widget.ArrayAdapter.CreateFromResource (Android.Content.Context context, System.Int32 textArrayResId, System.Int32 textViewResId) [0x0006d] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
      at AndroidApp1.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00031] in <51ce4ed05744482eb8a8079a399a17d2>:0
      at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
      at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.3(intptr,intptr,intptr)

This commit adds synchronization of the `SkipInJavaToManaged` property
which results in the sample attached to the GitHub issue to work
properly.

Note: for some weird reason the error occurred *only* with the *Release*
build of `Mono.Android.dll` and *only* in the framework v9.0 (that is
API28) - if the app targetted any other API it would not fail.  I can't
see why this would be so since the relevant code was very similar
between v9.0 and other frameworks and it was *identical* in case of
the *Debug* build of the v9.0 framework.
jonpryor pushed a commit that referenced this issue Jun 22, 2020
Fixes: #4809
Context: 7117414
Context: a017561

Part of commit a017561 dealt with mappings from certain Java types
which point to the same Managed type by making sure that they all refer
to the same type definition and managed type name.  However, in doing
so it failed to synchronize the property which indicates that we are
dealing with an interface or generic type, in which case such a type
should be ignored by the type mapping code in the runtime.

In this particular case, the issue was with the `ArrayAdapter` type,
which has both generic and non-generic definitions, and it so happens
that the *first* type in `Mono.Android` assembly is the generic one,
thus it, and its duplicate, should be ignored but due to the failure to
synchronize the `SkipInJavaToManaged` property, the second instance of
the type was not skipped on the runtime, resulting in the following
exception:

	System.MemberAccessException: Cannot create an instance of Android.Widget.ArrayAdapter`1[T] because Type.ContainsGenericParameters is true.
	  at System.Reflection.RuntimeConstructorInfo.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
	  at System.Reflection.RuntimeConstructorInfo.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
	  at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
	  at Java.Interop.TypeManager.CreateProxy (System.Type type, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x0001b] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Interop.TypeManager.CreateInstance (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type targetType) [0x00111] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Lang.Object.GetObject (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type type) [0x00023] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Lang.Object._GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00017] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Lang.Object.GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Android.Widget.ArrayAdapter.CreateFromResource (Android.Content.Context context, System.Int32 textArrayResId, System.Int32 textViewResId) [0x0006d] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at AndroidApp1.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00031] in <51ce4ed05744482eb8a8079a399a17d2>:0
	  at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.3(intptr,intptr,intptr)

This commit adds synchronization of the `SkipInJavaToManaged` property
which results in the sample attached to the GitHub issue to work
properly.

Note: for some weird reason the error occurred *only* with the
*Release* build of `Mono.Android.dll` and *only* with
`$(TargetFrameworkVersion)`=v9.0 (API-28); if the app used any other
framework version it would not fail.  I can't see why this would be so
since the relevant code was very similar between v9.0 and other
frameworks and it was *identical* in case of the *Debug* build of the
v9.0 framework.
jonpryor pushed a commit that referenced this issue Jun 23, 2020
Fixes: #4809
Context: 7117414
Context: a017561

Part of commit a017561 dealt with mappings from certain Java types
which point to the same Managed type by making sure that they all refer
to the same type definition and managed type name.  However, in doing
so it failed to synchronize the property which indicates that we are
dealing with an interface or generic type, in which case such a type
should be ignored by the type mapping code in the runtime.

In this particular case, the issue was with the `ArrayAdapter` type,
which has both generic and non-generic definitions, and it so happens
that the *first* type in `Mono.Android` assembly is the generic one,
thus it, and its duplicate, should be ignored but due to the failure to
synchronize the `SkipInJavaToManaged` property, the second instance of
the type was not skipped on the runtime, resulting in the following
exception:

	System.MemberAccessException: Cannot create an instance of Android.Widget.ArrayAdapter`1[T] because Type.ContainsGenericParameters is true.
	  at System.Reflection.RuntimeConstructorInfo.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00054] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
	  at System.Reflection.RuntimeConstructorInfo.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
	  at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <d772a4bbe86c4dc5b425d8ca91786b91>:0
	  at Java.Interop.TypeManager.CreateProxy (System.Type type, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x0001b] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Interop.TypeManager.CreateInstance (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type targetType) [0x00111] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Lang.Object.GetObject (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type type) [0x00023] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Lang.Object._GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00017] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Java.Lang.Object.GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at Android.Widget.ArrayAdapter.CreateFromResource (Android.Content.Context context, System.Int32 textArrayResId, System.Int32 textViewResId) [0x0006d] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at AndroidApp1.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00031] in <51ce4ed05744482eb8a8079a399a17d2>:0
	  at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <43cddc76fe22432dbdbcea2397b6fcd7>:0
	  at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.3(intptr,intptr,intptr)

This commit adds synchronization of the `SkipInJavaToManaged` property
which results in the sample attached to the GitHub issue to work
properly.

Note: for some weird reason the error occurred *only* with the
*Release* build of `Mono.Android.dll` and *only* with
`$(TargetFrameworkVersion)`=v9.0 (API-28); if the app used any other
framework version it would not fail.  I can't see why this would be so
since the relevant code was very similar between v9.0 and other
frameworks and it was *identical* in case of the *Debug* build of the
v9.0 framework.
@brendanzagaeski
Copy link
Contributor Author

Release status update

A new Preview version of Xamarin.Android has now been published that includes the fix for this item. The fix is not yet included in a Release version. I will update this again when a Release version is available that includes the fix.

Fix included in Xamarin.Android 11.0.0.3.

Fix included on Windows in Visual Studio 2019 version 16.7 Preview 4. To try the Preview version that includes the fix, check for the latest updates in Visual Studio Preview.

Fix included on macOS in Visual Studio 2019 for Mac version 8.7 Preview 4. To try the Preview version that includes the fix, check for the latest updates on the Preview updater channel.

@brendanzagaeski
Copy link
Contributor Author

Release status update

A new Release version of Xamarin.Android has now been published that includes the fix for this item.

Fix included in Xamarin.Android SDK version 11.0.0.3.

Fix included on Windows in Visual Studio 2019 version 16.7. To get the new version that includes the fix, check for the latest updates or install the most recent release from https://visualstudio.microsoft.com/downloads/.

Fix included on macOS in Visual Studio 2019 for Mac version 8.7. To get the new version that includes the fix, check for the latest updates on the Stable updater channel.

@ghost ghost locked as resolved and limited conversation to collaborators Jun 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: App Runtime Issues in `libmonodroid.so`. regression
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants