Bug 43609 - [Cycle 8] App exits on launch due to "The following assembly referenced from Java.Interop.dll could not be loaded: ... System.Runtime" if both the linker and shared runtime are enabled, unless the user also explicitly linkskips the facade assemblies
Summary: [Cycle 8] App exits on launch due to "The following assembly referenced from ...
Status: VERIFIED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 7.0 (C8)
Hardware: Macintosh Mac OS
: High major
Target Milestone: 7.0 (C8)
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2016-08-22 17:24 UTC by David Schwegler
Modified: 2016-08-25 23:08 UTC (History)
6 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

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 on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED FIXED

Description David Schwegler 2016-08-22 17:24:01 UTC
It appears something broke in the current Alpha (6.2.0.36). My coworker is on a previous alpha (6.2.0.33), and it works for him. Rolling back to stable (6.1.2.21) avoids the crash for me (and switching back to Alpha fails again). Is there a file that's missing somewhere on the current Alpha?

Problem: In release mode things work fine, but in debug mode the app crashes at startup. At the end of the AOT module loading block, Java.Interop/System.Runtime fails.

[Mono] AOT module 'Java.Interop.dll.so' not found: dlopen failed: library "/data/app/com.logos.androidlogos-1/lib/x86/libaot-Java.Interop.dll.so" not found
[Mono] AOT module '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/mono/aot-cache/x86/Java.Interop.dll.so' not found: dlopen failed: library "/data/app/com.logos.androidlogos-1/lib/x86/libaot-Java.Interop.dll.so" not found
[Mono] Config attempting to parse: 'Java.Interop.dll.config'.
[Mono] Config attempting to parse: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/etc/mono/assemblies/Java.Interop/Java.Interop.config'.
[Mono] Assembly Ref addref Mono.Android[0xf3f69280] -> Java.Interop[0xf3f692e0]: 2
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/mono/gac/System.Runtime/4.0.0.0__b03f5f7f11d50a3a/System.Runtime.dll'.
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/System.Runtime.dll'.
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/mono/gac/System.Runtime/4.0.0.0__b03f5f7f11d50a3a/System.Runtime.exe'.
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/System.Runtime.exe'.
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/mono/gac/System.Runtime/4.0.0.0__b03f5f7f11d50a3a/System.Runtime.dll'.
[Mono] Assembly Loader probing location: '/System.Runtime.dll'.
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/System.Runtime.dll'.
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/mono/gac/System.Runtime/4.0.0.0__b03f5f7f11d50a3a/System.Runtime.exe'.
[Mono] Assembly Loader probing location: '/System.Runtime.exe'.
[Mono] Assembly Loader probing location: '/Users/builder/data/lanes/3511/f7421548/source/monodroid/builds/install/mono-x86/lib/System.Runtime.exe'.
[Mono] The following assembly referenced from Java.Interop.dll could not be loaded:
[Mono] Assembly: System.Runtime (assemblyref_index=1)
[Mono] Version: 4.0.0.0
[Mono] Public Key: b03f5f7f11d50a3a
[Mono] The assembly was not found in the Global Assembly Cache, a path listed in the MONO_PATH environment variable, or in the location of the executing assembly (/).
[Mono] Failed to load assembly Java.Interop[0xf3f692e0]
[mono-rt] Stacktrace:

Version info from my alpha, my coworker's alpha, and my stable follow:

~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~

6.1.2.21 Stable works for me:

=== Xamarin Studio Community ===

Version 6.0.2 (build 73)
Installation UUID: b8e55913-dd86-416f-8bf9-112a7c76c3e2
Runtime:
Mono 4.4.2 (mono-4.4.0-branch-c7sr1/f72fe45) (64-bit)
GTK+ 2.24.23 (Raleigh theme)

Package version: 404020011

=== Xamarin.Profiler ===

Not Installed

=== Apple Developer Tools ===

Xcode 7.3.1 (10188.1)
Build 7D1014

=== Xamarin.Mac ===

Not Installed

=== Xamarin.Android ===

Version: 6.1.2.21 (Xamarin Studio Community)
Android SDK: /Users/dschwegler/Library/Developer/Xamarin/android-sdk-macosx
Supported Android versions:
4.0.3 (API level 15)
4.4 (API level 19)
5.0 (API level 21)
6.0 (API level 23)

SDK Tools Version: 25.1.7
SDK Platform Tools Version: 24.0.1
SDK Build Tools Version: 24.0.0

Java SDK: /usr
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Android Player ===

Version: 0.6.5
Location: /Applications/Xamarin Android Player.app

=== Xamarin.iOS ===

Version: 9.8.2.22 (Xamarin Studio Community)
Hash: f37444a
Branch: cycle7-sr1
Build date: 2016-07-28 12:17:02-0400

=== Build Information ===

Release ID: 600020073
Git revision: a6f7a24a9723a2d4f5d33c176615b0d44703ab5b
Build date: 2016-07-26 13:36:15-04
Xamarin addins: f5acb37866a0141bc5ddbe95118f18dae4014568
Build lane: monodevelop-lion-cycle7-sr1

=== Operating System ===

Mac OS X 10.11.5
Darwin ws2046.lrscorp.net 15.5.0 Darwin Kernel Version 15.5.0
Tue Apr 19 18:36:36 PDT 2016
root:xnu-3248.50.21~8/RELEASE_X86_64 x86_64

~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~

6.2.0.33 Alpha works for my coworker:

=== Xamarin Studio Community ===
Version 6.1 (build 5338)
Installation UUID: 286b0d49-7966-4996-bfca-0e87d79c78ef
Runtime:
Mono 4.6.0 (mono-4.6.0-branch/e571108) (64-bit)
GTK+ 2.24.23 (Raleigh theme)
Package version: 406000138
=== NuGet ===
Version: 3.4.3.0
=== Xamarin.Profiler ===
Not Installed
=== Xamarin.Android ===
Version: 6.2.0.33 (Xamarin Studio Community)
Android SDK: /Users/roy.dammarell/Library/Android/sdk
Supported Android versions:
2.3 (API level 10)
4.0.3 (API level 15)
4.1 (API level 16)
4.3 (API level 18)
4.4 (API level 19)
5.0 (API level 21)
5.1 (API level 22)
6.0 (API level 23)
SDK Tools Version: 25.2.1
SDK Platform Tools Version: 24.0.1
SDK Build Tools Version: 24.0.0
Java SDK: /usr
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL
=== Xamarin Android Player ===
Version: 0.6.5
Location: /Applications/Xamarin Android Player.app
=== Apple Developer Tools ===
Xcode 7.3.1 (10188.1)
Build 7D1014
=== Xamarin.Mac ===
Not Installed
=== Xamarin.iOS ===
Version: 9.99.2.40 (Xamarin Studio Community)
Hash: 40db5d1
Branch: cycle8
Build date: 2016-08-11 18:59:56-0400
=== Xamarin Inspector ===
Version: 0.8.1.0
Hash: 95792d1
Branch: master
Build date: Thu May 12 22:20:04 UTC 2016
=== Build Information ===
Release ID: 601005338
Git revision: 860f5d2e358077f913badaf7b14c5532888bf12c
Build date: 2016-08-11 16:20:43-04
Xamarin addins: 8bea879bcb4de08213fff5812fd54323d79889d6
Build lane: monodevelop-lion-cycle8
=== Operating System ===
Mac OS X 10.11.6
Darwin ws2100-14071.local 15.6.0 Darwin Kernel Version 15.6.0
Thu Jun 23 18:25:34 PDT 2016
root:xnu-3248.60.10~1/RELEASE_X86_64 x86_64
=== Enabled user installed addins ===
Paket 0.1
Xamarin Inspector 0.8.1.0


~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~

6.2.0.36 Alpha does not work for me:

=== Xamarin Studio Community ===

Version 6.1 (build 5345)
Installation UUID: b8e55913-dd86-416f-8bf9-112a7c76c3e2
Runtime:
Mono 4.6.0 (mono-4.6.0-branch/d0fc1a6) (64-bit)
GTK+ 2.24.23 (Raleigh theme)

Package version: 406000150

=== NuGet ===

Version: 3.4.3.0

=== Xamarin.Profiler ===

Not Installed

=== Xamarin.Android ===

Version: 6.2.0.36 (Xamarin Studio Community)
Android SDK: /Users/dschwegler/Library/Developer/Xamarin/android-sdk-macosx
Supported Android versions:
4.0.3 (API level 15)
4.4 (API level 19)
5.0 (API level 21)
6.0 (API level 23)

SDK Tools Version: 25.1.7
SDK Platform Tools Version: 24.0.1
SDK Build Tools Version: 24.0.0

Java SDK: /usr
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Android Player ===

Version: 0.6.5
Location: /Applications/Xamarin Android Player.app

=== Apple Developer Tools ===

Xcode 7.3.1 (10188.1)
Build 7D1014

=== Xamarin.iOS ===

Version: 9.99.3.8 (Xamarin Studio Community)
Hash: 9eca876
Branch: cycle8
Build date: 2016-08-16 18:22:42-0400

=== Xamarin.Mac ===

Not Installed

=== Build Information ===

Release ID: 601005345
Git revision: fc3ab7c0cc891ef8c9867558d026257fc4654758
Build date: 2016-08-16 18:26:59-04
Xamarin addins: 695f42de8ea790cc717ccd388f2becfa35e704ae
Build lane: monodevelop-lion-cycle8

=== Operating System ===

Mac OS X 10.11.5
Darwin ws2046.lrscorp.net 15.5.0 Darwin Kernel Version 15.5.0
Tue Apr 19 18:36:36 PDT 2016
root:xnu-3248.50.21~8/RELEASE_X86_64 x86_64
Comment 1 Artyom 2016-08-22 21:57:58 UTC
Try off Fast Assembly Deployment
Comment 2 David Schwegler 2016-08-22 22:01:26 UTC
@Artyom We currently do not use fast deployment.
Comment 3 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-22 22:30:50 UTC
It sounds like `System.Runtime.dll` is not ending up in the expected deployed location for the app.


A couple quick initial questions:


1. Just to gather a bit more information about your particular deployment configuration, if you might be able to attach the `.csproj` for your project (optionally privately) that might come in handy.  You can optionally remove all of the `<Compile Include="...">` lines.  I'm thinking there might be some combination of deployment settings, linker settings, debugging settings, etc. that might be be playing a part in the problem.


2. Have you by chance double-checked that the bad behavior still happens after you do a "hard clean" of the project (remove all the `bin` and `obj` folders and manually uninstall the app from the test device)?


Thanks!
Comment 4 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-22 23:19:08 UTC
This appears to be a duplicate of a non-public internal bug that was filed by the Xamarin QA team.

To summarize the non-public bug, one cause of this error is if the both the shared runtime and the managed linker are enabled.  The candidate fix for that issue (that will be included in the next Alpha/Beta version of Cycle 8) disables the linker automatically if the shared runtime is enabled:

https://github.com/xamarin/xamarin-android/commit/9465b1ec9c1fbfb948530aed72b3fdad286f5629
https://github.com/xamarin/xamarin-android/commit/8dae797b93a066da48f98bd2035a1b8bd97343e0
monodroid/cycle8/193425fb




## Workaround

1. Set "Project Options > Build > Android Build > Linker [tab] > Linker Behaviour" to "Don't Link" (in Xamarin Studio, for example).

2. Clean the project via "Build > Clean ..." (in Xamarin Studio, for example) and then re-deploy.



(If that workaround doesn't succeed in your case, please proceed with sending over the additional information from Comment 3, and then REOPEN the bug.  Thanks!)
Comment 5 David Schwegler 2016-08-23 00:04:33 UTC
Hi Brendan,

A few weeks ago I ran across Jon's comments on this thread (https://bugzilla.xamarin.com/show_bug.cgi?id=31527#c15). It's over a year old, so I assumed I *must* have misunderstood him or a better solution prevailed in the end. The fact that this actually went through is jaw-dropping to me.

I *cannot* emphasize how important it is to us that our developers be able to do their day-to-day development & debugging with linking enabled. Linking fundamentally changes what code gets shipped, and such errors are often extremely hard to find in testing. 

As a result of enabling the linker in debug mode, we significantly reduced our per-developer testing time (since we no longer had to develop in both Debug *and* Release modes) and went from a linker-related bug introduced every month to *zero* in over a year.

Can you please explain why you are removing support for such a important development feature?


======

Here are some related settings in our csproj's. 

Global:
    <AndroidEnableMultiDex>true</AndroidEnableMultiDex>
    <DebugType>full</DebugType>
    <AndroidLinkMode>Full</AndroidLinkMode>

Debug:
    <DebugSymbols>true</DebugSymbols>
    <Optimize>false</Optimize>
    <EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>

Release:
    <Optimize>true</Optimize>
    <AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
Comment 6 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-23 03:16:26 UTC
More investigation and consideration of the proper fix will quite possibly be warranted by the engineering team.  I am a member of the customer support team.  My activity on this bug report to date has been of a bookkeeping nature.  Also note that I used the term _candidate_ fix.
Comment 7 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-23 06:50:11 UTC
## Observations that might be informative

(The engineers might also be able to expand on these points.)



- If you build a new template "Blank Android App" with the shared runtime enabled, fast linking disabled, and linking disabled, the resulting .apk contains a few assemblies, including several "System.*" assemblies.  All of the "System.*" assemblies that are in the .apk itself are facade assemblies.

>   Length   Name
>  --------  ----
>      5120  assemblies/AndroidApp1.dll
>      1276  assemblies/AndroidApp1.dll.mdb
>     13312  assemblies/System.Runtime.dll
>      5632  assemblies/System.Threading.dll
>      5120  assemblies/System.Collections.dll
>      5120  assemblies/System.Collections.Concurrent.dll
>      4608  assemblies/System.Diagnostics.Debug.dll
>      5632  assemblies/System.Reflection.dll
>      4096  assemblies/System.Linq.dll
>      7680  assemblies/System.Runtime.InteropServices.dll
>      5120  assemblies/System.Runtime.Extensions.dll
>      4608  assemblies/System.Reflection.Extensions.dll


- In contrast, all of the non-facade system assemblies are absent from the .apk itself.  A few examples are `Mono.Android.dll`, `Java.Interop.dll`, `mscorlib.dll`, and `System.dll`.  Where are they?  In the shared runtime.  `Mono.Android.dll` is provided by the "Mono.Android.Platform.ApiLevel_23" (or other ApiLevel) .apk package.  All the other are provided by the "Mono.Android.DebugRuntime" .apk package.  Those 2 packages are the "shared runtime."



- What happens to the contents of the app .apk archive after the linker has been set to "Link SDK assemblies only"?  The "System.*" facade assemblies that were part of the app .apk are now absent:

>   Length   Name
>  --------  ----
>      5120  assemblies/AndroidApp1.dll
>      1276  assemblies/AndroidApp1.dll.mdb



## Possible explanation of why the note in the commit messages from Comment 4 says that "Link SDK assemblies" and "Shared Runtime" are contradictory

What does the "Link SDK assemblies only" setting do?  It removes unused types and methods from all of the assemblies that are shipped as part of the Xamarin SDK, including `Mono.Android.dll`, `Java.Interop.dll`, `mscorlib.dll`, and `System.dll`.

Given that fact, what does it mean to have "Link SDK assemblies only" enabled when the shared runtime is also enabled?  It means that the only assemblies that could possibly have a different behavior at run time compared to "Don't Link" would be the facade assemblies.  All of the non-facade SDK assemblies are instead loaded from the shared runtime, so they are _not_ linked.

It would therefore seem that enabling "Link SDK assemblies only" while the shared runtime is enabled would _not_ be very helpful as a way to detect _run time_ linker errors in the Debug build.  So perhaps the significant reduction in per-developer test time mentioned in Comment 5 was instead about _build time_ errors?


### Can this reasoning account for the particular error message on this bug?

I think there's a good chance that it can.  The story might be:

- `Java.Interop.dll` is linked at _build time_ because "Link SDK assemblies" is enabled.

- When the linker is examining that assembly, the linker discovers that it can remove the `System.Runtime.dll` dependency entirely because `System.Runtime.dll` is no longer used by any remaining types or methods.

- Since there is no longer a reference to `System.Runtime.dll`, the build process also doesn't include the "unused" `System.Runtime.dll` facade into the `.apk`.

- **But** the shared runtime version of `Java.Interop.dll` that the app actually uses when _running_ on the device is _not_ linked, so it still references `System.Runtime.dll`, which is now missing.




## Possible alternatives



### Is it possible to debug with "Link SDK assemblies" enabled and the shared runtime _disabled_ (so that all the SDK assemblies will actually have the same _run time_ behavior they would in a Release build)?

Tentatively "yes".

This configuration seemed to work OK in my very brief initial test of setting a breakpoint in a "Blank Android App" template.



### Would it be possible to write custom build logic to have the managed linker perform a "dummy" linking pass just to test for _build time_ errors, and then discard the results when creating the actual app .apk?

Yes, I think this would be possible, but it would probably take a bit of experimentation and study.




## Note to the Xamarin engineers

If you notice anything that isn't accurate above, please do add corrections.  Thanks!


One small question I'm not yet sure about is why the shared runtime deployment style puts the facade assemblies in the app .apk rather than including them in the shared runtime.
Comment 8 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-23 07:36:12 UTC
## Note to the Xamarin engineers

Hmm.  Xamarin.Forms and 3rd-party libraries that set the `Android.LinkerSafe` attribute are another interesting case.

I suppose even then it would still be possible to enable linking for those assemblies while using the shared runtime.  You could switch to "Link all assemblies", and then exclude everything from linking except for those assemblies.  It might even be possible to add custom steps in the build process to detect all the "LinkerSafe" assemblies and then auto-generate the proper exclusion list to pass into the linker.
Comment 9 David Schwegler 2016-08-23 18:14:50 UTC
Hi Brendan,

Thanks for following up. Apologies if my response sounded too harsh. :)

Yes, we Link All (not just SDK Only)
<AndroidLinkMode>Full</AndroidLinkMode>

Runtime errors are our primary concern. We want to have confidence that our development product is functionally the same as (or very close to) our deployed product.

We heavily rely on a lot of non-sdk assemblies (such as MvvmCross). For example, enabling linking in debug mode when using MvvmCross is important because that uses a lot of reflection, and so will crash in release mode at runtime in subtle ways if we haven't got the linking setup correctly during development.

Seems like the solutions are:
- Fix linking when using the shared runtime in debug mode (ideal)
- Disable use of the shared runtime in debug mode when linking is enabled (disappointing)
- Only link non-shared-runtime assemblies in debug mode (pretty gross)

It would be disappointing if we couldn't use the shared runtime anymore -- our app is very large (~70mb release linked) and the deployment time is already quite significant. However, disabling all linking itself is much worse, so we'd have to do that.
Comment 10 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-23 18:57:14 UTC
> - Only link non-shared-runtime assemblies in debug mode (pretty gross)

To fill in a detail on that, it sounds like "only link non-shared-runtime assemblies" is in fact the end goal you are trying to achieve: you wish to have a "hybrid" linking setup where you can test linking on external assemblies while still using the non-linked shared runtime.  So I'm imagining "pretty gross" is from the perspective that at the moment one would have to manually linkskip all of the system assemblies because that filtering logic is not currently built into Xamarin.Android?

In theory Xamarin.Android could provide a special additional linker setting (perhaps an additional boolean parameter) that would explicitly skip all of the system assemblies.  Setting this "skip only the SDK assemblies" parameter to be enabled by default for "Link SDK assemblies only" + shared runtime seems like it might break the principle of "least surprise" since that linker mode is after all _called_ "Link SDK assemblies only" (so if it was also skipping linking all of the SDK assemblies, then it would be "surprising" that it was still linking _anything_, namely the external "LinkerSafe" assemblies).  On the other hand, "Link _all_ assemblies" + shared runtime is a slightly different story.  Maybe in that case it would be "not entirely surprising" to skip the system assemblies automatically and link everything else.  One concern is that it would still be a little "surprising" for the _build time_ behavior (because it wouldn't hit any of the possible build time errors that might arise when linking the system assemblies).

More contemplation might be needed about whether such a "hybrid" mode would best be added as an explicit built-in feature of Xamarin.Android or perhaps provided as a small additional NuGet package (or similar) that a user could add to a project to change the default behavior of linker enabled + shared runtime enabled.
Comment 11 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-23 19:42:12 UTC
## Note to the Xamarin team

Hmmmmmmmm.  It looks like the current LinkAssemblies Task has in fact always (for many years) done the "surprising" thing.  It _does_ already automatically skip the shared runtime assemblies in the "Link SDK assemblies only" + shared runtime configuration:

https://github.com/xamarin/xamarin-android/blob/3885fcc55c244bef6fd109ac6b7b9abc8fb6ab38/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs#L102-L103



So at first glance the candidate fix from Comment 4 seems sort of redundant.  Why is the linker rewriting the assembly references for `Java.Interop.dll` even though that assembly is linkskipped?  Is that necessary?




## References before linking

> $ monop --refs -r:AndroidApp1/obj/Debug/linksrc/Java.Interop.dll
> System.Threading, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Collections, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Collections.Concurrent, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Diagnostics.Debug, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Reflection, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Runtime.InteropServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Runtime.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
> System.Reflection.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a



## References after linking

> $ monop --refs -r:AndroidApp1/obj/Debug/android/assets/Java.Interop.dll
> mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
> mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
> System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
> System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Comment 12 David Schwegler 2016-08-23 19:53:25 UTC
Brendan,

It sounds like we're getting on the same page, thank you. :) 

Given the behavior you described, if clear/non-surprising is the issue, perhaps simpler would be adding "Non-SDK assemblies only" to the linker modes. Enabling "Use Shared Runtime" would only be allowed if linking was set to that or "None".
Comment 13 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-23 19:58:00 UTC
> Why is the linker rewriting the assembly references for `Java.Interop.dll` even though that assembly is linkskipped?

Ohhhh, right.  It seems to be due to the facade assemblies because those are _not_ part of `Profile.SharedRuntimeAssemblies`, so they are not automatically linkskipped.




## Workaround

Manually add the following string under "Project Options > Build > Android Build > Linker [tab] > Ignore assemblies":

System.Runtime;System.Threading;System.Collections;System.Collections.Concurrent;System.Diagnostics.Debug;System.Reflection;System.Linq;System.Runtime.InteropServices;System.Runtime.Extensions;System.Reflection.Extensions


(If the app uses other shared runtime assemblies that refer to other facade assemblies, you'd need to add those too.  One way to find the complete list is to look in the non-linked shared runtime .apk (as seen at the top of Comment 7).)



### Results

The app now runs without error.




## Note to the Xamarin team

Would it potentially be appropriate to revert the candidate fix from Comment 4 and instead automatically linkskip all of the facade assemblies whenever the shared runtime is enabled?

This also goes back to the question from the end of Comment 7 about why the shared runtime deployment style puts the facade assemblies in the app .apk rather than including them in the shared runtime.
Comment 14 Radek Doulik 2016-08-25 15:54:45 UTC
The fix from comment #4 also saves build time, so I think it is good idea to keep it.

We already put facade assemblies in the shared runtime, see https://github.com/xamarin/monodroid/commit/1a1ee82d46416ab94864a97606329698e11e6b39
Comment 15 Brendan Zagaeski (Xamarin Team, assistant) 2016-08-25 23:08:26 UTC
Ah very cool!  Thanks for the additional info that the facade assemblies are now included in the shared runtime.

I can verify that the new Cycle 8 Beta 2 from yesterday no longer requires the manual workaround from Comment 13 to build and run in the "Link all assemblies" + shared runtime configuration.  I can also verify that it successfully links external assemblies as desired in that configuration.

I don't have a strong a preference about reverting the commits from Comment 4, especially now that the facade assemblies are included in the shared runtime.  After all (as mentioned in Comment 10), the old behavior of "Link SDK assemblies only" + shared runtime was arguably a bit "surprising" anyway.  I think it's fine to leave everything the way it is in Cycle 8 Beta 2.

So I will mark this bug as resolved.  Thanks for the fixes!




## Two (perhaps unnecessary) extra bits of cleanup


- In the "no linking" condition with the shared runtime enabled, Xamarin.Android still includes the facade assemblies in the app .apk.  I think it would be OK to skip bundling those into the app .apk now that they are all included in the shared runtime?  But this is at most only a very small issue, so there's no terrible urgency to address it.


- In the "Link all assemblies" configuration, the .apk does _not_ contain the facade assemblies.  Applying the workaround from Comment 13 causes those assemblies to again be bundled into the .apk.  This suggests to me that the linker might not currently be skipping the facade assemblies, so it might be appropriate to update the `Profile.SharedRuntimeAssemblies` list used at [1] to include the facade assemblies.

[1] https://github.com/xamarin/xamarin-android/blob/3885fcc55c244bef6fd109ac6b7b9abc8fb6ab38/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs#L102-L103




## Verification status: verified fixed in Cycle 8 Beta 2

GOOD: Xamarin.Android 6.2.0.47
(This corresponds to XamarinVS 4.2.0.584 on Windows)