Bug 53515 - F#: Loading images from files causes a null reference exception
Summary: F#: Loading images from files causes a null reference exception
Status: CONFIRMED
Alias: None
Product: Forms
Classification: Xamarin
Component: Android (show other bugs)
Version: 2.3.3
Hardware: PC Windows
: High normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2017-03-20 10:52 UTC by Rob Lyndon
Modified: 2017-08-31 15:05 UTC (History)
7 users (show)

Tags: ac android image f#
Is this bug a regression?: ---
Last known good build:


Attachments
Attached IDE logs (4.47 KB, application/x-zip-compressed)
2017-07-19 11:00 UTC, Saurabh Paunikar
Details
repro project (154.62 KB, application/zip)
2017-07-19 17:33 UTC, Jimmy [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report for Bug 53515 on Developer Community or GitHub if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: Developer Community HTML or GitHub Markdown
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description Rob Lyndon 2017-03-20 10:52:54 UTC
1. Create a new project, of type "Visual F# -> Android -> Blank App (Android)"

2. Add the Xamarin.Forms Nuget package.

3. Replace the code in MainActivity.fs with

namespace <<MyProjectName>>

open System

open Xamarin.Forms.Platform.Android

open Android.App
open Android.Content
open Android.OS
open Android.Runtime
open Android.Views
open Android.Widget

type MainPage() =
    inherit Xamarin.Forms.ContentPage()
    let layout = new Xamarin.Forms.StackLayout()
    do layout.Children.Add(new Xamarin.Forms.Button(Image = new Xamarin.Forms.FileImageSource(File = "Icon.jpg")))
    do base.Content <- layout

type App() =
    inherit Xamarin.Forms.Application()
    do base.MainPage <- new MainPage()

[<Activity (Label = "FSharpResourcesDemo", MainLauncher = true)>]
type MainActivity () =
    inherit FormsApplicationActivity()
    override this.OnCreate (bundle) =
        base.OnCreate (bundle)
        Xamarin.Forms.Forms.Init(this, bundle)
        this.LoadApplication(new App())

Run the app.

Boom.

Note that ImageSource.FromFile() breaks in exactly the same way.
Comment 1 Rob Lyndon 2017-03-20 11:00:34 UTC
Also, ImageSource.FromResource() seems to be working correctly.

For convenience, I have added a project called FSharpResourcesDemo to my open source project, https://github.com/SpiegelSoft/Astrid. If you clone this solution, you can set this project to be your startup project.

I'm giving a presentation at the F# Exchange on the 7th of April, so a proposed fix or a valid workaround by then would be very useful.
Comment 2 Rob Lyndon 2017-03-20 11:02:27 UTC
There is a partial workaround: by adding

type Drawable() = inherit Resource_Drawable()
type Id() = inherit Resource_Id()

to your MainActivity file, the error happens further down the stack, but it doesn't come anywhere near solving the problem.
Comment 3 Rob Lyndon 2017-03-20 11:36:26 UTC
I've found the cause.

In the Resource.designer.fs project, members are defined as follows:

    static member abc_ab_share_pack_mtrl_alpha = 2130837504

In F#, these are interpreted as properties, rather than fields.

So here is the fix for the Xamarin Forms project:

In the ResourceManager class in the Xamarin.Forms.Core project, replace the method

public static void Init(Assembly masterAssembly)
{
	DrawableClass = masterAssembly.GetTypes().FirstOrDefault(x => x.Name == "Drawable");
	ResourceClass = masterAssembly.GetTypes().FirstOrDefault(x => x.Name == "Id");
}


with

public static void Init(Assembly masterAssembly)
{
	DrawableClass = masterAssembly.GetTypes().FirstOrDefault(x => x.Name == "Drawable" || x.Name == "Resource_Drawable");
	ResourceClass = masterAssembly.GetTypes().FirstOrDefault(x => x.Name == "Id" || x.Name == "Resource_Id");
}

and then replace the GetId() method

static int GetId(Type type, string propertyName)
{
	FieldInfo[] props = type.GetFields();
	FieldInfo prop = props.Select(p => p).FirstOrDefault(p => p.Name == propertyName);
	if (prop != null)
		return (int)prop.GetValue(type);
	return 0;
}

with

static int GetId(Type type, string propertyName)
{
	FieldInfo[] props = type.GetFields();
	FieldInfo prop = type.GetFields().FirstOrDefault(p => p.Name == propertyName) || type.GetProperties().FirstOrDefault(p => p.Name == propertyName);
	if (prop != null)
		return (int)prop.GetValue(type);
	return 0;
}

I'll submit a pull request.
Comment 4 Rob Lyndon 2017-03-20 11:37:16 UTC
Apologies -- in the code above, replace || with the null propagation operator ??
Comment 5 Rob Lyndon 2017-03-20 18:06:02 UTC
The final implementation is 

static int GetId(Type type, string propertyName)
{
	object value = type.GetFields().FirstOrDefault(p => p.Name == propertyName)?.GetValue(type)
		?? type.GetProperties().FirstOrDefault(p => p.Name == propertyName)?.GetValue(type);
	if (value != null)
		return (int)value;
	return 0;
}

The pull request is https://github.com/xamarin/Xamarin.Forms/pull/825
Comment 6 Rui Marinho 2017-04-12 11:08:11 UTC
Should be fixed on 2.3.5-pre1
Comment 8 Saurabh Paunikar 2017-07-19 11:00:17 UTC
Created attachment 23652 [details]
Attached IDE logs
Comment 9 Jimmy [MSFT] 2017-07-19 17:33:41 UTC
Created attachment 23665 [details]
repro project

I've attached a project that uses Forms 2.3.5-pre6 and still reproduces the issue so I am re-confirming this report.

### Version Tests
2.3.6.120   BAD
2.3.5-pre6  BAD