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

Linker #1590

Closed
wants to merge 23 commits into from
Closed

Linker #1590

wants to merge 23 commits into from

Conversation

bgavrilMS
Copy link
Member

tracking bug: #1586
Things that don't work now: json exception.

@@ -4,6 +4,12 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
#if ANDROID_BUILDTIME
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use if ANDROID as we not hiding anything here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably the reason why the fix isn't working.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tried doing this with #if ANDROID but that did not seem to work. The only thing that did work was adding preserve to each of the classes. We can remove this from the AssemblyInfo

@bgavrilMS
Copy link
Member Author

bgavrilMS commented Jan 22, 2020

Context: the linker works by removing code that isn't used by your app. For example, if the customer uses the system webview, then all the code related to embedded webview will be removed.

The root cause for json exceptions:

  1. The LINKER looks at objects like ClientInfo and thinks - their constructors are are not used anywhere, so I can remove them! This is because MSAL doesn't use those constructors directly, but Newtonsoft invokes them thorough reflection. But Newtonsoft can't deserialize if constructors are removed :)
  2. I bet that the Linker knows about the old [DataContract] attributes but doesn't know about the new [JsonObject] attributes.

So the solution is either:

  1. to add the #if ANDROID || IOS [Preserve] attribute to ALL classes that we deserlialize, i.e. all classes that are decorated with  [JsonObject].
    OR
  2. Alternatively, we can add [assembly: LinkerSafe] to tell the linker to leave the entire assembly alone.

If we want to play nice with Xamarin, we should go with [Preserve] attributes. This will allow Xamarin to remove unused code form MSAL and produce a smaller apk. If we want to be more future proof, [assembly: LinkerSafe] is the answer - this will tell Xamarin to leave MSAL alone and if we add a new object that we deserialize, then we wouldn't have to add the [Preseve] attribute as well. But the size of APK will be larger, and customers may complain.

CC @henrik-me @trwalke @jennyf19

@bgavrilMS
Copy link
Member Author

LGTM

@@ -280,10 +280,12 @@ public void VerifyResult(ITestController controller)
}
else if (result.Contains(CoreUiTestConstants.TestResultFailureMessage))
{
controller.Tap("LogPage");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need all those else clauses because you are either returning or throwing, which breaks the flow anyway.

@hig-dev
Copy link

hig-dev commented Jan 23, 2020

I would not use something like:

#if iOS
using Foundation;
#endif
#if ANDROID
using Android.Runtime;
#endif

Instead declare a PreserveAttribute class and use that in the code:

public sealed class PreserveAttribute : System.Attribute {
    public bool AllMembers;
    public bool Conditional;
}

Then you can use it like:

    [PreserveAttribute(AllMembers = true)]
    public class ExampleClassToPreserve
    {
     ....
    }

This is a much cleaner solution.
Source: https://docs.microsoft.com/en-us/xamarin/ios/deploy-test/linker?tabs=macos#controlling-the-linker

@@ -311,7 +311,13 @@ private void CreateExceptionMessage(Exception exception)
acquireResponseLabel.Text = "Exception - " + exception.Message;
}

Console.WriteLine(exception);
Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Exception -\nMessage: {0}\nStack Trace: {1}",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you just replace the entire block with

Console.WriteLine(exception);

it will be enough. The exception.ToString() method takes care of outputting the message, the stack trace and the inner exception details

@bgavrilMS bgavrilMS closed this Jan 24, 2020
@jennyf19 jennyf19 deleted the jennyf/linker branch May 12, 2020 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants