You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Xamarin.Android.Tools.AndroidSdk] Attributes can be null! (#158)
Context: #157
Context: 2d3690e
Commit 2d3690e added Nullable Reference Type support to
`Xamarin.Android.Tools.AndroidSdk.dll`. Unfortunately, it was
largely "surface level", updating *public* API, but not all method
implementations were appropriately updated.
Case in point: if `$HOME/.config/xbuild/monodroid-config.xml`
contains *no* value in `<java-sdk/>`, e.g.
<monodroid>
<android-sdk path="/path/to/android/sdk" />
<java-sdk /> <!-- empty! -->
</monodroid>
then Visual Studio for Mac may report a first-chance exception
(only reported when debugging Visual Studio for Mac, as the exception
is caught internally):
{System.ArgumentNullException: Value cannot be null. (Parameter 'homePath')
at Xamarin.Android.Tools.JdkInfo..ctor(String homePath, String locator, Action`2 logger)}
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.JdkInfo.JdkInfo Line 55
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.JdkInfo.JdkInfo Line 99
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.JdkInfo.TryGetJdkInfo Line 347
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.JdkLocations.GetUnixPreferredJdks.AnonymousMethod__0 Line 14
at System.Linq.dll!System.Linq.Enumerable.SelectEnumerableIterator<string, Xamarin.Android.Tools.JdkInfo>.MoveNext
at System.Linq.dll!System.Linq.Enumerable.WhereSelectEnumerableIterator<Xamarin.Android.Tools.JdkInfo, Xamarin.Android.Tools.JdkInfo>.ToArray
at System.Linq.dll!System.Linq.Buffer<Xamarin.Android.Tools.JdkInfo>.Buffer
at System.Linq.dll!System.Linq.OrderedEnumerable<Xamarin.Android.Tools.JdkInfo>.GetEnumerator
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.JdkLocations.GetPreferredJdks Line 19
at System.Linq.dll!System.Linq.Enumerable.ConcatIterator<Xamarin.Android.Tools.JdkInfo>.MoveNext
at System.Linq.dll!System.Linq.Enumerable.SelectEnumerableIterator<Xamarin.Android.Tools.JdkInfo, string>.MoveNext
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.AndroidSdkBase.GetValidPath Line 112
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.AndroidSdkBase.Initialize Line 69
at Xamarin.Android.Tools.AndroidSdk.Ide.dll!Xamarin.Android.Tools.AndroidSdkInfo.AndroidSdkInfo
at Xamarin.AndroidTools.Ide.dll!Xamarin.AndroidTools.AndroidSdk.Refresh Line 53
…
A major reason to adopt Nullable Reference Types is to *prevent* the
occurrence of `NullReferenceException`s, so what went wrong?
What went wrong with 2d3690e is that when XML attributes don't
exist, [`XElement.Attribute()`][0] will return `null`, and most of
our `XElement.Attribute()` invocations cast the `XAttribute` return
value to `string`, "asserting" that a *non-`null`* is returned.
Review the codebase for all `XElement.Attribute()` invocations, and
update all casts from `(string)` to instead cast to `(string?)`.
This ensures that we don't circumvent the C# compilers Nullable
Reference Type checks, catches the circumvention which was present
in `JdkLocations.GetUnixConfiguredJdkPaths()`, and thus avoids the
first-chance exception that VSMac could see.
[0]: https://docs.microsoft.com/en-us/dotnet/api/system.xml.linq.xelement.attribute?view=net-6.0
Co-Authored by: @KirillOsenkov
0 commit comments