Skip to content

Conversation

@jonpryor
Copy link
Contributor

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+<GetLibexecJdkPaths>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)".
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array/>
</plist>
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.

{
if (logger == null)
throw new ArgumentNullException (nameof (logger));
logger = logger ?? DefaultConsoleLogger;
Copy link
Member

Choose a reason for hiding this comment

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

Should there also be an overload where you don’t have to pass a null logger?

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+<GetLibexecJdkPaths>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)".
	<?xml version="1.0" encoding="UTF-8"?>
	<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
	<plist version="1.0">
	<array/>
	</plist>
	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`.
@jonpryor jonpryor force-pushed the jonp-macos-no-jdks branch from 7ccd047 to 77f2683 Compare August 14, 2018 23:52
@jonpryor jonpryor merged commit bdf0158 into dotnet:master Aug 15, 2018
jonpryor added a commit that referenced this pull request Aug 15, 2018
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+<GetLibexecJdkPaths>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)".
	<?xml version="1.0" encoding="UTF-8"?>
	<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
	<plist version="1.0">
	<array/>
	</plist>
	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`.
jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this pull request Aug 16, 2018
grendello pushed a commit to dotnet/android that referenced this pull request Aug 17, 2018
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.

2 participants