From 77f2683fe60f48d2093fd246cfffc560be5e0db9 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 14 Aug 2018 17:32:58 -0400 Subject: [PATCH] Better support no installed JDKs on macOS What happens if there is no JDK installed on macOS? $ mv ~/Library/Developer/Xamarin/jdk ~/Library/Developer/Xamarin/jdk.bk $ sudo mv /Library/Java/JavaVirtualMachines /Library/Java/JavaVirtualMachines.bk `JdkInfo` doesn't like this, which is to be expected, but *how* it doesn't like it is...bad: $ csharp -r:bin/Debug/Xamarin.Android.Tools.AndroidSdk.dll csharp> Xamarin.Android.Tools.JdkInfo.GetKnownSystemJdkInfos(); Error getting SDK info: System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1. at System.Xml.XmlTextReaderImpl.Throw (System.Exception e) at System.Xml.XmlTextReaderImpl.Throw (System.String res, System.String arg) at System.Xml.XmlTextReaderImpl.Throw (System.String res) at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace () at System.Xml.XmlTextReaderImpl.ParseDocumentContent () at System.Xml.XmlTextReaderImpl.Read () at System.Xml.XmlReader.MoveToContent () at System.Xml.Linq.XElement.Load (System.Xml.XmlReader reader, System.Xml.Linq.LoadOptions options) at System.Xml.Linq.XElement.Parse (System.String text, System.Xml.Linq.LoadOptions options) at System.Xml.Linq.XElement.Parse (System.String text) at Xamarin.Android.Tools.JdkInfo+d__54.MoveNext () ... Er, what? The problem is the output of `/usr/libexec/java_home -X`: $ /usr/libexec/java_home -X Unable to find any JVMs matching version "(null)". No Java runtime present, try --request to install. What's happening is that `java_home` is writing XML to stdout, and an error message to stderr. `ProcessUtils.Exec()`, meanwhile, was *merging **both*** `stdout` and `stderr` into *one* stream, and the result was *not* valid XML, hence the `XmlException`. The fix? Allow `stderr` to be separate from `stdout`, so that `JdkInfo.GetLibexecJdkPaths()` can get valid XML. Additionally, because I'm finding it increasingly annoying needing to provide the `logger` parameter to `AndroidSdkInfo`/etc., update the `AndroidSdkInfo` constructor so that `logger` is *optional*. If it isn't provided, we'll write our log messages to `System.Console`. --- src/Xamarin.Android.Tools.AndroidSdk/AndroidSdkInfo.cs | 5 ++--- src/Xamarin.Android.Tools.AndroidSdk/JdkInfo.cs | 2 +- src/Xamarin.Android.Tools.AndroidSdk/ProcessUtils.cs | 6 ++++-- .../Tests/AndroidSdkInfoTests.cs | 7 ------- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/Xamarin.Android.Tools.AndroidSdk/AndroidSdkInfo.cs b/src/Xamarin.Android.Tools.AndroidSdk/AndroidSdkInfo.cs index 7e710bc..5738fb1 100644 --- a/src/Xamarin.Android.Tools.AndroidSdk/AndroidSdkInfo.cs +++ b/src/Xamarin.Android.Tools.AndroidSdk/AndroidSdkInfo.cs @@ -10,10 +10,9 @@ public class AndroidSdkInfo { AndroidSdkBase sdk; - public AndroidSdkInfo (Action logger, string androidSdkPath = null, string androidNdkPath = null, string javaSdkPath = null) + public AndroidSdkInfo (Action logger = null, string androidSdkPath = null, string androidNdkPath = null, string javaSdkPath = null) { - if (logger == null) - throw new ArgumentNullException (nameof (logger)); + logger = logger ?? DefaultConsoleLogger; sdk = CreateSdk (logger); sdk.Initialize (androidSdkPath, androidNdkPath, javaSdkPath); diff --git a/src/Xamarin.Android.Tools.AndroidSdk/JdkInfo.cs b/src/Xamarin.Android.Tools.AndroidSdk/JdkInfo.cs index 6e1026a..d73b748 100644 --- a/src/Xamarin.Android.Tools.AndroidSdk/JdkInfo.cs +++ b/src/Xamarin.Android.Tools.AndroidSdk/JdkInfo.cs @@ -345,7 +345,7 @@ static IEnumerable GetLibexecJdkPaths (Action logger if (string.IsNullOrEmpty (e.Data)) return; xml.Append (e.Data); - }); + }, includeStderr: false); var plist = XElement.Parse (xml.ToString ()); foreach (var info in plist.Elements ("array").Elements ("dict")) { var JVMHomePath = (XNode) info.Elements ("key").FirstOrDefault (e => e.Value == "JVMHomePath"); diff --git a/src/Xamarin.Android.Tools.AndroidSdk/ProcessUtils.cs b/src/Xamarin.Android.Tools.AndroidSdk/ProcessUtils.cs index 87b02ca..352eb77 100644 --- a/src/Xamarin.Android.Tools.AndroidSdk/ProcessUtils.cs +++ b/src/Xamarin.Android.Tools.AndroidSdk/ProcessUtils.cs @@ -131,7 +131,7 @@ public static Task ExecuteToolAsync (string exe, Func logger = null; - Assert.Throws (() => new AndroidSdkInfo (logger)); - } - [Test] public void Constructor_Paths () {