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

[BUG] System.Reflection.TargetInvocationException on BitmapLoader.Current #330

Closed
brim-borium opened this issue May 28, 2019 · 19 comments · Fixed by #359
Closed

[BUG] System.Reflection.TargetInvocationException on BitmapLoader.Current #330

brim-borium opened this issue May 28, 2019 · 19 comments · Fixed by #359

Comments

@brim-borium
Copy link

Describe the bug
I am using akavache and LoadImageFromUrl(key,url,fetchalways,...) method. As I can see this calls the BitmapLoader.Current.Load() method this throws an exception. Possible the Reflection of the PlatformBitmapLoader fails when BitmapLoader.Current is called

Expected behavior
An image is loaded 😁

Environment(please complete the following information):

  • OS: Android (iOS is fine)
  • Akavache: 5.0.0 (can't use any other right now)
  • Splat: 3.0.0 (can't use any other right now)

Additional context

{
    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.-- - > System.TypeInitializationException: The type initializer
    for 'Splat.PlatformBitmapLoader'
    threw an exception.-- - > System.InvalidOperationException: Sequence contains no matching element
    at System.Linq.Enumerable.First[TSource](System.Collections.Generic.IEnumerable `1[T] source, System.Func`
        2[T, TResult] predicate)[0x00011] in < ba85ba5122c3499483c4d8a7ac6f7e5a >: 0
    at Splat.PlatformBitmapLoader..cctor()[0x00026] in < b69f18e916c449f19b169602282b9d0f >: 0
        -- - End of inner exception stack trace-- -
        at(wrapper managed - to - native) System.Reflection.MonoCMethod.InternalInvoke(System.Reflection.MonoCMethod, object, object[], System.Exception & )
    at System.Reflection.MonoCMethod.InternalInvoke(System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions)[0x00005] in < 58604 b4522f748968296166e317b04b4 >: 0
        -- - End of inner exception stack trace-- -
        at System.Reflection.MonoCMethod.InternalInvoke(System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions)[0x0001a] in < 58604 b4522f748968296166e317b04b4 >: 0
    at System.RuntimeType.CreateInstanceMono(System.Boolean nonPublic, System.Boolean wrapExceptions)[0x000a8] in < 58604 b4522f748968296166e317b04b4 >: 0
    at System.RuntimeType.CreateInstanceSlow(System.Boolean publicOnly, System.Boolean wrapExceptions, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark & stackMark)[0x00009] in < 58604 b4522f748968296166e317b04b4 >: 0
    at System.RuntimeType.CreateInstanceDefaultCtor(System.Boolean publicOnly, System.Booean skipCheckThis, System.Boolean fillCache, System.Boolean wrapExceptions, System.Threading.StackCrawlMark & stackMark)[0x00027] in < 58604 b4522f748968296166e317b04b4 >: 0
    at System.Activator.CreateInstance(System.Type type, System.Boolean nonPublic, System.Boolean wrapExceptions)[0x0002c] in < 58604 b4522f748968296166e317b04b4 >: 0
    at System.Activator.CreateInstance(System.Type type, System.Boolean nonPublic)[0x00000] in < 58604 b4522f748968296166e317b04b4 >: 0
    at System.Activator.CreateInstance(System.Type type)[0x00000] in < 58604 b4522f748968296166e317b04b4 >: 0
    at Splat.AssemblyFinder.AttemptToLoadType[T](System.String fullTypeName)[0x000bb] in < b69f18e916c449f19b169602282b9d0f >: 0
    at Splat.BitmapLoader..cctor()[0x00000] in < b69f18e916c449f19b169602282b9d0f >: 0
}


{
    System.TypeInitializationException: The type initializer
    for 'Splat.PlatformBitmapLoader'
    threw an exception.-- - > System.InvalidOperationException: Sequence contains no matching element
    at System.Linq.Enumerable.First[TSource](System.Collections.Generic.IEnumerable `1[T] source, System.Func`
        2[T, TResult] predicate)[0x00011] in < ba85ba5122c3499483c4d8a7ac6f7e5a >: 0
    at Splat.PlatformBitmapLoader..cctor()[0x00026] in < b69f18e916c449f19b169602282b9d0f >: 0
        -- - End of inner exception stack trace-- -
        at(wrapper managed - to - native) System.Reflection.MonoCMethod.InternalInvoke(System.Reflection.MonoCMethod, object, object[], System.Exception & )
    at System.Reflection.MonoCMethod.InternalInvoke(System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions)[0x00005] in < 58604 b4522f748968296166e317b04b4 >: 0
}


{
    System.InvalidOperationException: Sequence contains no matching element
    at System.Linq.Enumerable.First[TSource](System.Collections.Generic.IEnumerable `1[T] source, System.Func`
        2[T, TResult] predicate)[0x00011] in < ba85ba5122c3499483c4d8a7ac6f7e5a >: 0
    at Splat.PlatformBitmapLoader..cctor()[0x00026] in < b69f18e916c449f19b169602282b9d0f >: 0
}
@brim-borium brim-borium changed the title [BUG] Summary of item [BUG] System.Reflection.TargetInvocationException on BitmapLoader.Current May 28, 2019
@glennawatson
Copy link
Contributor

What version of Android are you using?

@brim-borium
Copy link
Author

brim-borium commented May 28, 2019

currently testing on android 7.0 and using visual studio for mac with xamarin.android Version: 9.2.3.0

@glennawatson
Copy link
Contributor

Ah that's be likely why. Our minimum is Android 81

@brim-borium
Copy link
Author

Devices with Android 9 and 8 are also not working

@glennawatson
Copy link
Contributor

I'm talking about in your target framework not so much the devices.

@brim-borium
Copy link
Author

Target is 8.1

@glennawatson
Copy link
Contributor

I will have a look at it tomorrow my time for you. See what I can find.

@alexshikov
Copy link
Contributor

We have similar crashes for users with on Android 8.0 devices according to Fabric...

@alexshikov
Copy link
Contributor

alexshikov commented Jun 7, 2019

After some debug, there is a weird thing happening:

  • .GetAssemblies() contains assembly with a name __callback_factory__, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null.
  • SelectMany(x => x.GetTypes() throws an excption for that assembly
Exception of type 'System.Reflection.ReflectionTypeLoadException' was thrown.
Type '__callback_factory__class__' is not finished

An interesting thing is this assembly is dynamic, so only line of code fixes the issue:

var assemblies = System.AppDomain.CurrentDomain.GetAssemblies ()
    .Where (x => !x.IsDynamic)
    .SelectMany (x => x.GetTypes ())
    ...

@dpvreony
Copy link
Member

dpvreony commented Jun 8, 2019

potential fix in #337 but is there a better way than to skip all dynamic assemblies if they could have a genuine use case for generating drawable resources via reflection? (not sure they do, merely posing the question)

@IamTobi unfortunately this won't be an immediate help to you if you are blocked on akavache 5\splat 3.

@alexshikov
Copy link
Contributor

Any idea oh how to use a local method for assembly loading?
Currently, the crash happening in a static constructor, so the path to Splat.BitmapLoader.Current = new MyAndroidBitmapLoader() can't be reached...
The NuGet package can't be removed, as there are a few other libraries that reference Splat.

So far the only workaround I see is to keep the original NuGet reference but replace the DLL reference in the project to the custom one (that built from the source code using fixed assembly loading).

Is there any better solution to try?

@dpvreony
Copy link
Member

just to clarify - do you mean having a custom splat v3?

what's blocking you getting onto v7?

moving forward we can probably do something to allow service locator registration of platformbitmap loader
public static void InitializeSplat(this IMutableDependencyResolver resolver)

@alexshikov
Copy link
Contributor

alexshikov commented Jun 11, 2019

We have a bit outdated production that uses Splat 2.0.0 and development that uses the latest 7.2.1.
We can't easily update production to the newer version because of other libraries - to much hustle.

I've tried to follow the next approach:

  1. Copy source code of PlatformBitmapLoader to the project from Splat 2.0.0 release
  2. Modify static PlatformBitmapLoader() logic to fix an issue
  3. On app setup replace plugin singleton with custom implementation Splat.BitmapLoader.Current = new MyAndroidBitmapLoader()

Usually that helps, but in the current case the problem happens before .Current setter invoked:

private static IBitmapLoader _Current = AssemblyFinder.AttemptToLoadType<IBitmapLoader>("Splat.PlatformBitmapLoader");

Also, the latest Splat NuGet package still has the issue and we need the fix now.

@glennawatson
Copy link
Contributor

glennawatson commented Jun 11, 2019

Also, the latest Splat NuGet package still has the issue and we need the fix now.

I don't see you contributing to the project nor your employer? We don't commit to any sort of timeline since everyone here is basically volunteering their time. https://www.youtube.com/watch?v=Mm_RuObpeGo for some ideas why sometimes open source developers are jerks.

Essentially @dpvreony when his life permits will get that fix out there in the wild, and if we have per our open collective policy https://opencollective.com/reactiveui a sponsor we are happy to give those issues priority.

Thanks.

YouTube
As software developers we often make use of open-source software (OSS) but do we ever think about all the man hours that go into developing and supporting th...
An advanced, composable, functional reactive model-view-viewmodel framework for all .NET platforms!

@alexshikov
Copy link
Contributor

@glennawatson I'm sorry for being impolite. I didn't have attention to insult or force to fix an issue.

I just wanted to point out that I understand that the fix won't be available immediately, and we just looking for a local workaround while the new version is released.

Hoped to get your thoughts, if you see any better solution then described.

@glennawatson
Copy link
Contributor

I will see how far away @dpvreony is coming from the fix. That is a fairly standard reply if people start requesting changes immediately and stuff. There is definitely a problem where sometimes clients of open source products tend to expect guaranteed support levels and stuff so no offense intended and none taken.

@dpvreony
Copy link
Member

dpvreony commented Jun 11, 2019

the challenge is splat v3 can't use an assembly rebind to v7.x because of the amount of breaking changes that have happened.

exceptions in static constructors basically mean the type is never available in the appdomain. the way the platformbitmap is set up makes it a bit difficult to retrospectively interact with. I touched on us changing the initialisation to allow injecting like you can do with the DI locator. but again that's future and won't solve your problem.

can you confirm you are using vs2017 or vs2019? other issues rearing their head recently are down to a change in vs2019 and xamarin. so if that's the case you could build with vs2017.

if you need a v2/v3 capable library you may to take a fork of v3 and copy the fix

https://github.com/mono/mono/blob/22887567e1663b101c37fa29ec1613175337f944/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.cs#L820 is where the issue is occuring. I need to build a unit test and run it on the android test runner. I removed part of a fix on checking the dynamic type yesterday as I thought the try \ catch should handle it, but having looked at mono i'm not convinced.

GitHub
Mono open source ECMA CLI, C# and .NET implementation. - mono/mono

@glennawatson
Copy link
Contributor

Was this fixed in v8 for you guys?

dpvreony added a commit that referenced this issue Jul 15, 2019
@dpvreony
Copy link
Member

followed up the quick fix with unit tests in test runner. and flexibility in the splat init to allow the default bitmap loader to be changed

image

@lock lock bot added the outdated label Oct 13, 2019
@lock lock bot locked and limited conversation to collaborators Oct 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants