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

@(JavaSourceJar) & JDK11 #4789

Closed
jonpryor opened this issue Jun 9, 2020 · 3 comments · Fixed by #5253
Closed

@(JavaSourceJar) & JDK11 #4789

jonpryor opened this issue Jun 9, 2020 · 3 comments · Fixed by #5253
Assignees
Labels
Area: Bindings Issues in Java Library Binding projects.

Comments

@jonpryor
Copy link
Member

jonpryor commented Jun 9, 2020

@(JavaSourceJar) can be is a way to extract parameter name information from Javadoc files, and use that parameter name information within a .jar binding.

See e.g. https://github.com/xamarin/xamarin-android/blob/a111f6704d640481a6a85234ec4aa86ddbc18c3a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs#L434-L451

With the introduction of JDK 11 support #4567, @(JavaSourceJar) support is unfortunately broken, in part because JDK 11's javadoc utility emits different HTML, which isn't currently supported.

Steps to Reproduce

  1. Revert the JavaSourceJar-related changes from PR JetBrains OpenJDK 11 #4567
  2. Run the BindingBuildTest.JavaSourceJar() unit test
  3. Watch it fail.

Expected Behavior

The unit test should work!

Actual Behavior

It doesn't.

Version Information

Log File

@jonpryor jonpryor added the Area: Bindings Issues in Java Library Binding projects. label Jun 9, 2020
@jonpryor
Copy link
Member Author

jonpryor commented Jun 9, 2020

In-progress (and incomplete) xamarin-android patch to fix javadoc-to-mdoc.exe:

diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Documentation.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Documentation.targets
index ad1e824a..c31086f5 100644
--- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Documentation.targets
+++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Documentation.targets
@@ -16,12 +16,7 @@ This file is only used by binding projects. .NET 5 can eventually use it, once `
   <UsingTask TaskName="Xamarin.Android.Tasks.MDoc"          AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
   <UsingTask TaskName="Xamarin.Android.Tasks.Unzip"         AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
 
-  <PropertyGroup>
-    <_JavadocSupported Condition=" $(_JdkVersion.StartsWith ('1.8')) ">True</_JavadocSupported>
-  </PropertyGroup>
-
   <Target Name="_ExtractJavaDocJars"
-      Condition=" '$(_JavadocSupported)' == 'True' "
       Inputs="@(JavaDocJar)"
       Outputs="@(JavaDocJar->'$(IntermediateOutputPath)javadocs\%(FileName).stamp')">
     <Unzip
@@ -35,7 +30,6 @@ This file is only used by binding projects. .NET 5 can eventually use it, once `
   </Target>
 
   <Target Name="_GenerateJavaDocFromSourceJars"
-      Condition=" '$(_JavadocSupported)' == 'True' "
       Inputs="@(JavaSourceJar)"
       Outputs="@(JavaSourceJar->'$(IntermediateOutputPath)javadocs\%(FileName).stamp')">
     <Unzip
@@ -57,9 +51,9 @@ This file is only used by binding projects. .NET 5 can eventually use it, once `
   </Target>
 
   <Target Name="BuildDocumentation"
-      Condition=" '@(JavaDocIndex)' != '' And '$(_JavadocSupported)' == 'True' "
       Inputs="@(JavaDocIndex);@(IntermediateAssembly->'$(IntermediateOutputPath)%(filename).xml')"
-      Outputs="@(IntermediateAssembly->'$(OutputPath)%(filename).xml')">
+      Outputs="@(IntermediateAssembly->'$(OutputPath)%(filename).xml')"
+      Condition=" '@(JavaDocIndex)' != '' ">
     <MDoc
         References="@(ReferencePath);@(ReferenceDependencyPaths)"
         TargetAssembly="@(IntermediateAssembly)"
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/JavaDoc.cs b/src/Xamarin.Android.Build.Tasks/Tasks/JavaDoc.cs
index a139415e..8e79e613 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/JavaDoc.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/JavaDoc.cs
@@ -40,12 +40,19 @@ namespace Xamarin.Android.Tasks
 				context_src = pair.Source;
 				context_dst = pair.Destination;
 				base.RunTask ();
+				try {
+					File.Delete (context_responseFile);
+				}
+				catch (Exception e) {
+					Log.LogDebugMessage ($"Could not delete temporary file `{context_responseFile}`: {e.ToString ()}");
+				}
 			}
-			return true;
+			return !Log.HasLoggedErrors;
 		}
 
 		string context_src;
 		string context_dst;
+		string context_responseFile;
 
 		protected override string GenerateCommandLineCommands ()
 		{
@@ -55,8 +62,6 @@ namespace Xamarin.Android.Tasks
 			cmd.AppendFileNameIfNotNull (context_dst);
 			cmd.AppendSwitch ("-sourcepath");
 			cmd.AppendFileNameIfNotNull (context_src);
-			cmd.AppendSwitch ("-subpackages");
-			cmd.AppendSwitch (".");
 			var cps = ReferenceJars?.ToList () ?? new List<string> ();
 			if (JavaPlatformJar != null)
 				cps.Add (JavaPlatformJar);
@@ -70,6 +75,18 @@ namespace Xamarin.Android.Tasks
 				foreach (var extraArg in ExtraArgs)
 					cmd.AppendSwitch (extraArg);
 
+			context_responseFile    = Path.GetTempFileName ();
+			cmd.AppendSwitch ($"\"@{context_responseFile}\"");
+
+			var javaSources = Directory.EnumerateFiles (context_src, "*.java", SearchOption.AllDirectories)
+				.Select (file => Path.GetFullPath (file))
+				.ToList ();
+			File.AppendAllLines (context_responseFile, javaSources, MonoAndroidHelper.UTF8withoutBOM);
+			Log.LogDebugMessage ($"Response file `{context_responseFile}` contains: ");
+			foreach (var file in javaSources) {
+				Log.LogDebugMessage ($"  {file}");
+			}
+
 			return cmd.ToString ();
 		}
 
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs
index 51ca9f7e..58db90e6 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs
@@ -445,38 +445,11 @@ namespace Foo {
 					BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64)
 				});
 				Assert.IsTrue (bindingBuilder.Build (binding), "binding build should have succeeded");
-				var jdkVersion = GetJdkVersion ();
-				if (jdkVersion > new Version (9, 0)) {
-					Assert.Ignore ("JDK 11 and @(JavaSourceJar) don't currently mix.");
-					return;
-				}
 				string xml = bindingBuilder.Output.GetIntermediaryAsText ("docs/Com.Xamarin.Android.Test.Msbuildtest/JavaSourceJarTest.xml");
 				Assert.IsTrue (xml.Contains ("<param name=\"name\"> - name to display.</param>"), "missing doc");
 			}
 		}
 
-		static Version GetJdkVersion ()
-		{
-			var jdkPath     = AndroidSdkResolver.GetJavaSdkPath ();
-			var releasePath = Path.Combine (jdkPath, "release");
-			if (!File.Exists (releasePath))
-				return null;
-			foreach (var line in File.ReadLines (releasePath)) {
-				const string JavaVersionStart = "JAVA_VERSION=\"";
-				if (!line.StartsWith (JavaVersionStart, StringComparison.OrdinalIgnoreCase))
-					continue;
-				var value   = line.Substring (JavaVersionStart.Length, line.Length - JavaVersionStart.Length - 1);
-				int last    = 0;
-				for (last = 0; last < value.Length; ++last) {
-					if (char.IsDigit (value, last) || value [last] == '.')
-						continue;
-					break;
-				}
-				return Version.Parse (last == value.Length ? value : value.Substring (0, last));
-			}
-			return null;
-		}
-
 		[Test]
 		[TestCaseSource (nameof (ClassParseOptions))]
 		public void DesignTimeBuild (string classParser)
diff --git a/src/Xamarin.Android.Tools.JavadocImporter/DocumentElement.cs b/src/Xamarin.Android.Tools.JavadocImporter/DocumentElement.cs
index 962ea487..819075df 100644
--- a/src/Xamarin.Android.Tools.JavadocImporter/DocumentElement.cs
+++ b/src/Xamarin.Android.Tools.JavadocImporter/DocumentElement.cs
@@ -410,4 +410,35 @@ namespace Xamarin.Android.Tools.JavaDocToMdoc
 			});
 		}
 	}
+
+	class JavaDoc11DocumentElement : JavaDoc7DocumentElement
+	{
+		public JavaDoc11DocumentElement (MdocHelper mdoc, XElement documentElement)
+			: base (mdoc, documentElement)
+		{
+		}
+
+		public override DocumentSection CreateSection (XElement sectionAnchor, string anchor, RegisterAttribute mregister)
+		{
+			return new JavaDoc11DocumentSection (sectionAnchor) {
+					Anchor              = anchor,
+					Mdoc                = Mdoc,
+					RegisterAttribute   = mregister,
+			};
+		}
+
+		public override XElement GetSectionAnchor (string localAnchor)
+		{
+			localAnchor = localAnchor.Replace (" ", string.Empty);
+			while (localAnchor.IndexOf ('<') >= 0 && localAnchor.IndexOf ('>') > localAnchor.IndexOf ('<'))
+				localAnchor = localAnchor.Substring (0, localAnchor.IndexOf ('<')) + localAnchor.Substring (localAnchor.IndexOf ('>') + 1);
+			localAnchor = localAnchor;
+			return Element.Descendants ("a").FirstOrDefault (a => {
+				var h = (string) a.Attribute ("id");
+				if (h == null || h != localAnchor)
+					return false;
+				return true;
+			});
+		}
+	}
 }
diff --git a/src/Xamarin.Android.Tools.JavadocImporter/DocumentSection.cs b/src/Xamarin.Android.Tools.JavadocImporter/DocumentSection.cs
index d858cf82..40e394ce 100644
--- a/src/Xamarin.Android.Tools.JavadocImporter/DocumentSection.cs
+++ b/src/Xamarin.Android.Tools.JavadocImporter/DocumentSection.cs
@@ -480,4 +480,24 @@ namespace Xamarin.Android.Tools.JavaDocToMdoc
 				.Select (n => n.NodeType == XmlNodeType.Text ? new XElement ("p", n) : n);
 		}
 	}
+
+	class JavaDoc11DocumentSection : JavaDocDocumentSection
+	{
+		public JavaDoc11DocumentSection (XElement anchorNode)
+			: base (anchorNode.ElementsAfterSelf ("ul").Elements ("li").FirstOrDefault ())
+		{
+		}
+
+		public override string SectionNameWrapperTag {
+			get { return "span"; }
+		}
+
+		public override IEnumerable<XNode> GetSummaryNodes ()
+		{
+			var div = section_node.Elements ("div").FirstOrDefault ();
+			return div == null ? Enumerable.Empty<XNode> () : div.Nodes ()
+				.Where (n => n.NodeType != XmlNodeType.Text || ((XText)n).Value.Length > 0)
+				.Select (n => n.NodeType == XmlNodeType.Text ? new XElement ("p", n) : n);
+		}
+	}
 }
diff --git a/src/Xamarin.Android.Tools.JavadocImporter/HtmlLoader.cs b/src/Xamarin.Android.Tools.JavadocImporter/HtmlLoader.cs
index 28a39fab..9d03e539 100644
--- a/src/Xamarin.Android.Tools.JavadocImporter/HtmlLoader.cs
+++ b/src/Xamarin.Android.Tools.JavadocImporter/HtmlLoader.cs
@@ -53,9 +53,11 @@ namespace Xamarin.Android.Tools.JavaDocToMdoc
 		{
 			DroidDoc,
 			DroidDoc2,
+			Java,
 			Java6,
 			Java7,
-			Java8
+			Java8,
+			Java11,
 		}
 
 		Sgml.SgmlDtd HtmlDtd;
@@ -87,6 +89,9 @@ namespace Xamarin.Android.Tools.JavaDocToMdoc
 				return new JavaDoc7DocumentElement (new JavaDocMdocHelper (), jd);
 			case JavaDocKind.Java8:
 				return new JavaDoc8DocumentElement (new JavaDocMdocHelper (), jd);
+			case JavaDocKind.Java:
+			case JavaDocKind.Java11:
+				return new JavaDoc11DocumentElement (new JavaDocMdocHelper (), jd);
 			}
 			throw new InvalidOperationException ();
 		}
@@ -115,10 +120,15 @@ namespace Xamarin.Android.Tools.JavaDocToMdoc
 				kind = JavaDocKind.DroidDoc2;
 			if (rawHTML.Substring (0, Math.Min (rawHTML.Length, 500)).IndexOf ("Generated by javadoc (build 1.6", StringComparison.Ordinal) > 0)
 				kind = JavaDocKind.Java6;
-			if (rawHTML.Substring (0, Math.Min (rawHTML.Length, 500)).IndexOf ("Generated by javadoc (version 1.7", StringComparison.Ordinal) > 0)
+			else if (rawHTML.Substring (0, Math.Min (rawHTML.Length, 500)).IndexOf ("Generated by javadoc (version 1.7", StringComparison.Ordinal) > 0)
 				kind = JavaDocKind.Java7;
-			if (rawHTML.Substring (0, Math.Min (rawHTML.Length, 500)).IndexOf ("Generated by javadoc (1.8", StringComparison.Ordinal) > 0)
+			else if (rawHTML.Substring (0, Math.Min (rawHTML.Length, 500)).IndexOf ("Generated by javadoc (1.8", StringComparison.Ordinal) > 0)
 				kind = JavaDocKind.Java8;
+			else if (rawHTML.Substring (0, Math.Min (rawHTML.Length, 500)).IndexOf ("Generated by javadoc (11.", StringComparison.Ordinal) > 0)
+				kind = JavaDocKind.Java11;
+			else if (rawHTML.Substring (0, Math.Min (rawHTML.Length, 500)).IndexOf ("Generated by javadoc ", StringComparison.Ordinal) > 0)
+				kind = JavaDocKind.Java;
+
 			if (kind == JavaDocKind.DroidDoc) {
 				throw new NotSupportedException ("Old DroidDoc is not supported anymore.");
 			} else {

@jonpryor
Copy link
Member Author

jonpryor commented Jun 9, 2020

In-progress (and incomplete) changes to Java.Interop allow reading of JDK11 Javadoc:

commit 280b9ce7f399f50aea1499fa37b40f482356c93c
Author: Jonathan Pryor <jonpryor@vt.edu>
Date:   Thu May 28 18:54:40 2020 -0400

    Javadoc 11 support?

diff --git a/external/xamarin-android-tools b/external/xamarin-android-tools
index 23c4fe0..f5fcb9f 160000
--- a/external/xamarin-android-tools
+++ b/external/xamarin-android-tools
@@ -1 +1 @@
-Subproject commit 23c4fe0a989f8d0887786fdee6db635387597c13
+Subproject commit f5fcb9fd1583ebe928734e8525303a0dbe93c79c
diff --git a/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs b/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs
index 62adb9a..5909c4a 100644
--- a/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs
+++ b/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs
@@ -19,6 +19,8 @@ namespace Xamarin.Android.Tools.Bytecode {
 		Java8,
 		_ApiXml,
 		JavaApiParameterNamesXml,
+		Java,
+		Java11,
 	}
 
 	public class ClassPath {
@@ -247,9 +249,11 @@ namespace Xamarin.Android.Tools.Bytecode {
 			switch (JavaMethodParameterNameProvider.GetDocletType (src)) {
 			default: return new DroidDoc2Scraper (src);
 			case JavaDocletType.DroidDoc: return new DroidDocScraper (src);
-			case JavaDocletType.Java6: return new JavaDocScraper (src);
+			case JavaDocletType.Java: return new JavaDocScraper (src);
+			case JavaDocletType.Java6: return new Java6DocScraper (src);
 			case JavaDocletType.Java7: return new Java7DocScraper (src);
 			case JavaDocletType.Java8: return new Java8DocScraper (src);
+			case JavaDocletType.Java11: return new Java11DocScraper (src);
 			case JavaDocletType._ApiXml: return new ApiXmlDocScraper (src);
 			case JavaDocletType.JavaApiParameterNamesXml: return new JavaParameterNamesLoader (src);
 			}
diff --git a/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs b/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs
index 3adb738..a52e164 100644
--- a/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs
+++ b/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs
@@ -83,13 +83,13 @@ namespace Xamarin.Android.Tools.Bytecode
 		}
 	}
 
-	class JavaDocScraper : AndroidDocScraper
+	class Java6DocScraper : AndroidDocScraper
 	{
 		const String pattern_head_javadoc = "<TD><CODE><B><A HREF=\"[./]*"; // I'm not sure how path could be specified... (./ , ../ , or even /)
 		const String reset_pattern_head_javadoc = "<TD><CODE>";
 		const String parameter_pair_splitter_javadoc = "&nbsp;";
 	
-		public JavaDocScraper (string dir)
+		public Java6DocScraper (string dir)
 			: base (dir, pattern_head_javadoc, reset_pattern_head_javadoc, parameter_pair_splitter_javadoc, false)
 		{
 		}
@@ -129,6 +129,35 @@ namespace Xamarin.Android.Tools.Bytecode
 		}
 	}
 
+	class Java11DocScraper : AndroidDocScraper
+	{
+		const String pattern_head_javadoc = "<td class=\"col.+\" scope=\"row\"><code><span class=\"memberNameLink\"><a href=\"[./]*";
+		const String reset_pattern_head_javadoc = "<td><code>";
+		const String parameter_pair_splitter_javadoc = "&nbsp;";
+
+		public Java11DocScraper (string dir)
+			: base (dir, pattern_head_javadoc, reset_pattern_head_javadoc, parameter_pair_splitter_javadoc, true, "\\-", "\\-", "\\-", null)
+		{
+			ShouldAlterArraySpec = true;
+			ShouldEliminateGenericArguments = true;
+		}
+
+		protected override string StripTagsFromParameters (string value)
+		{
+			// Java8 javadoc contains possibly linked types with <a> tags, so remove all of them.
+			while (value.IndexOf ('<') >= 0 && value.IndexOf ('>') > value.IndexOf ('<'))
+				value = value.Substring (0, value.IndexOf ('<')) + value.Substring (value.IndexOf ('>') + 1);
+			return value;
+		}
+	}
+
+	class JavaDocScraper : Java11DocScraper {
+		public JavaDocScraper (string dir)
+			: base (dir)
+		{
+		}
+	}
+
 	public abstract class AndroidDocScraper : IJavaMethodParameterNameProvider
 	{
 		readonly String pattern_head;
@@ -163,8 +192,14 @@ namespace Xamarin.Android.Tools.Bytecode
 				throw new Exception ("Directory '" + dir + "' does not exist");
 	
 			root = dir;
+
+			var packageFiles = new[]{
+				Path.Combine (dir, "package-list"),
+				Path.Combine (dir, "packages.html"),
+				Path.Combine (dir, "allpackages-index.html"),
+			};
 	
-			if (!File.Exists (Path.Combine (dir, "package-list")) && !File.Exists (Path.Combine (dir, "packages.html")))
+			if (!packageFiles.Any (File.Exists))
 				throw new ArgumentException ("Directory '" + dir + "' does not appear to be an android doc reference directory.");
 			
 			//foreach (var f in Directory.GetFiles (dir, "*.html", SearchOption.AllDirectories))
@@ -319,6 +354,10 @@ namespace Xamarin.Android.Tools.Bytecode
 					kind = JavaDocletType.Java7;
 				else if (rawHTML.Contains ("Generated by javadoc (1.8"))
 					kind = JavaDocletType.Java8;
+				else if (rawHTML.Contains ("Generated by javadoc (11."))
+					kind = JavaDocletType.Java11;
+				else if (rawHTML.Contains ("Generated by javadoc "))
+					kind = JavaDocletType.Java;
 			}
 
 			// Check to see if it's an api.xml formatted doc

jonpryor added a commit that referenced this issue Jun 9, 2020
Context: https://issuetracker.google.com/issues/150189789
Context: https://developer.android.com/preview/features#signature-scheme-v4
Context: https://developer.android.com/preview/features#incremental

Preliminary JDK 11 support.

The Android SDK Build-tools r30.0.0-rc4 package currently requires
JDK 11 in order to use `apksigner.jar`:

	Task "AndroidApkSigner"
	  Task Parameter:ApkSignerJar=C:\Users\dlab14\android-toolchain\sdk\build-tools\30.0.0-rc4\lib\apksigner.jar
	  …
	  Task Parameter:ToolPath=C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.25\bin
	  Task Parameter:ManifestFile=obj\Release\android\AndroidManifest.xml
	  C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.25\bin\java.exe -jar C:\Users\dlab14\android-toolchain\sdk\build-tools\30.0.0-rc4\lib\apksigner.jar sign --ks "C:\Users\dlab14\AppData\Local\Xamarin\Mono for Android\debug.keystore" --ks-pass pass:android --ks-key-alias androiddebugkey --key-pass pass:android --min-sdk-version 21 --max-sdk-version 29  "C:\A\vs2019xam00000Y-1\_work\1\s\bin\TestRelease\temp\BuildAotApplication AndÜmläüts_x86_64_True_True\bin\Release\UnnamedProject.UnnamedProject-Signed.apk"
	  java.lang.UnsupportedClassVersionError: com/android/apksigner/ApkSignerTool has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
	  at java.lang.ClassLoader.defineClass1(Native Method)
	  …
	…\Xamarin.Android.Common.targets(2559,2): error MSB6006: "java.exe" exited with code 1.

This could be triggered by using the Android SDK Manager to install
Build-tools r30.0.0-rc4, then overriding the
`$(AndroidSdkBuildToolsVersion)` MSBuild property in `App.csproj`:

	<PropertyGroup>
	  <AndroidSdkBuildToolsVersion>30.0.0-rc4</AndroidSdkBuildToolsVersion>
	</PropertyGroup>

Many previous commits have added support for JDK 11, e.g. d99facb,
dcee2c8, 4742d50, 89f3dc1, and 895b7bc (among many others).

Additionally, c8ab455 updated the build environment so that *both*
JetBrains OpenJDK 1.8 and 11 were installed, though 1.8 was still used.

Now it's time to "flip the build environment," and use JDK 11 to build
the product, installers, and run (most) unit tests:

  * Update `azure-pipelines.yaml` and `azure-pipelines-oss.yaml` so
    that JDK 11 is used to build everything.

  * Update `xaprepare` so that when `$(JavaSdkDirectory)` isn't
    overridden, JDK 11 is used by default.

  * Override the `JI_JAVA_HOME` environment variable when preparing
    `external/Java.Interop` so that it uses the desired JDK.

  * Update the default `$(LatestSupportedJavaVersion)` value to
    11.0.4, the version of the JDK we install.

  * Update the `<ValidateJavaVersions/>` task so that JDK 11 is
    required when `$(AndroidSdkBuildToolsVersion)` is >= r30.
    This will cause an XA0032 error if JDK 1.8 is used to build a
    project when `$(AndroidSdkBuildToolsVersion)` is >= r30.

  * `apksigner` from Build-tools r30 creates a new `.idsig` file
    next to the `.apk`.  This is to enable a new
    `adb install --incremental` feature.  Add the `.idsig` file
    to `@(FileWrites)`.

  * Update various unit test `.csproj` files to consistently
    `<Import/>` the `Configuration.props` file and use properties
    within it for default values.  This in particular allowed building
    e.g. `samples/HelloWorld` to implicitly use JDK 11.

  * Increase "expected" times in
    `tests/msbuild-times-reference/MSBuildDeviceIntegration.csv`
    as JDK 11 appears to be slower than JDK 1.8 (🙁).

  * *Disable* support for `@(JavaSourceJar)` when JDK 11 is used.
    JDK 11 changes the HTML generated by the `javadoc` command, and
    we need to update our HTML parser to handle it.  In the interest
    of expediency, disable this for now.

The Android Designer integration tests continue to use JDK 1.8,
as the Designer doesn't currently build under JDK 11.

TODO:

  * Fix `@(JavaSourceJar)` support:
    #4789
  * Allow Android Designer to work with JDK 11, run Designer
    integration tests using JDK 11.
  * Figure out how to not accidentally bitrot JDK 1.8 support.

Co-authored-by: Jonathan Pryor <jonpryor@vt.edu>
Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com>
Co-authored-by: Jonathan Pobst <jonathan.pobst@microsoft.com>
Co-authored-by: Peter Collins <pecolli@microsoft.com>
jonpryor added a commit that referenced this issue Jun 9, 2020
Context: https://issuetracker.google.com/issues/150189789
Context: https://developer.android.com/preview/features#signature-scheme-v4
Context: https://developer.android.com/preview/features#incremental

Preliminary JDK 11 support.

The Android SDK Build-tools r30.0.0-rc4 package currently requires
JDK 11 in order to use `apksigner.jar`:

	Task "AndroidApkSigner"
	  Task Parameter:ApkSignerJar=C:\Users\dlab14\android-toolchain\sdk\build-tools\30.0.0-rc4\lib\apksigner.jar
	  …
	  Task Parameter:ToolPath=C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.25\bin
	  Task Parameter:ManifestFile=obj\Release\android\AndroidManifest.xml
	  C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.25\bin\java.exe -jar C:\Users\dlab14\android-toolchain\sdk\build-tools\30.0.0-rc4\lib\apksigner.jar sign --ks "C:\Users\dlab14\AppData\Local\Xamarin\Mono for Android\debug.keystore" --ks-pass pass:android --ks-key-alias androiddebugkey --key-pass pass:android --min-sdk-version 21 --max-sdk-version 29  "C:\A\vs2019xam00000Y-1\_work\1\s\bin\TestRelease\temp\BuildAotApplication AndÜmläüts_x86_64_True_True\bin\Release\UnnamedProject.UnnamedProject-Signed.apk"
	  java.lang.UnsupportedClassVersionError: com/android/apksigner/ApkSignerTool has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
	  at java.lang.ClassLoader.defineClass1(Native Method)
	  …
	…\Xamarin.Android.Common.targets(2559,2): error MSB6006: "java.exe" exited with code 1.

This could be triggered by using the Android SDK Manager to install
Build-tools r30.0.0-rc4, then overriding the
`$(AndroidSdkBuildToolsVersion)` MSBuild property in `App.csproj`:

	<PropertyGroup>
	  <AndroidSdkBuildToolsVersion>30.0.0-rc4</AndroidSdkBuildToolsVersion>
	</PropertyGroup>

Many previous commits have added support for JDK 11, e.g. d99facb,
dcee2c8, 4742d50, 89f3dc1, and 895b7bc (among many others).

Additionally, c8ab455 updated the build environment so that *both*
JetBrains OpenJDK 1.8 and 11 were installed, though 1.8 was still used.

Now it's time to "flip the build environment," and use JDK 11 to build
the product, installers, and run (most) unit tests:

  * Update `azure-pipelines.yaml` and `azure-pipelines-oss.yaml` so
    that JDK 11 is used to build everything.

  * Update `xaprepare` so that when `$(JavaSdkDirectory)` isn't
    overridden, JDK 11 is used by default.

  * Override the `JI_JAVA_HOME` environment variable when preparing
    `external/Java.Interop` so that it uses the desired JDK.

  * Update the default `$(LatestSupportedJavaVersion)` value to
    11.0.4, the version of the JDK we install.

  * Update the `<ValidateJavaVersions/>` task so that JDK 11 is
    required when `$(AndroidSdkBuildToolsVersion)` is >= r30.
    This will cause an XA0032 error if JDK 1.8 is used to build a
    project when `$(AndroidSdkBuildToolsVersion)` is >= r30.

  * `apksigner` from Build-tools r30 creates a new `.idsig` file
    next to the `.apk`.  This is to enable a new
    `adb install --incremental` feature.  Add the `.idsig` file
    to `@(FileWrites)`.

  * Update various unit test `.csproj` files to consistently
    `<Import/>` the `Configuration.props` file and use properties
    within it for default values.  This in particular allowed building
    e.g. `samples/HelloWorld` to implicitly use JDK 11.

  * Increase "expected" times in
    `tests/msbuild-times-reference/MSBuildDeviceIntegration.csv`
    as JDK 11 appears to be slower than JDK 1.8 (🙁).

  * *Disable* support for `@(JavaSourceJar)` when JDK 11 is used.
    JDK 11 changes the HTML generated by the `javadoc` command, and
    we need to update our HTML parser to handle it.  In the interest
    of expediency, disable this for now.

The Android Designer integration tests continue to use JDK 1.8,
as the Designer doesn't currently build under JDK 11.

TODO:

  * Fix `@(JavaSourceJar)` support:
    #4789
  * Allow Android Designer to work with JDK 11, run Designer
    integration tests using JDK 11.
  * Figure out how to not accidentally bitrot JDK 1.8 support.

Co-authored-by: Jonathan Pryor <jonpryor@vt.edu>
Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com>
Co-authored-by: Jonathan Pobst <jonathan.pobst@microsoft.com>
Co-authored-by: Peter Collins <pecolli@microsoft.com>
@grendello grendello added this to the Under Consideration milestone Jun 16, 2020
@jonpryor
Copy link
Member Author

jonpryor commented Aug 3, 2020

Better solution: dotnet/java-interop#687.

jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Nov 20, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Nov 21, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Nov 21, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Nov 22, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Nov 22, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Nov 22, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Nov 22, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Dec 7, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

For .NET 6 ("One .NET") integration purposes, provide a default item
group of `@(JavaSourceJar)` which includes `**\*-source?.jar` and
`**\*-src.jar`.  This will allow `dotnet build` of an "Android Java
Library Binding" project (`dotnet new android-bindinglib`) to
automatically process `.java` source code for documentation
translation purposes.

Finally, add `Java.Interop.Tools.Generator.dll` to the
`Microsoft.Android.Sdk*.nupkg` file, as it is an assembly dependency
of `generator.dll`.  (Not sure why this didn't previously fail…)

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Dec 8, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

For .NET 6 ("One .NET") integration purposes, provide a default item
group of `@(JavaSourceJar)` which includes `**\*-source?.jar` and
`**\*-src.jar`.  This will allow `dotnet build` of an "Android Java
Library Binding" project (`dotnet new android-bindinglib`) to
automatically process `.java` source code for documentation
translation purposes.

Finally, add `Java.Interop.Tools.Generator.dll` to the
`Microsoft.Android.Sdk*.nupkg` file, as it is an assembly dependency
of `generator.dll`.  (Not sure why this didn't previously fail…)

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Dec 10, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

For .NET 6 ("One .NET") integration purposes, provide a default item
group of `@(JavaSourceJar)` which includes `**\*-source?.jar` and
`**\*-src.jar`.  This will allow `dotnet build` of an "Android Java
Library Binding" project (`dotnet new android-bindinglib`) to
automatically process `.java` source code for documentation
translation purposes.

Add `Java.Interop.Tools.Generator.dll` to the
`Microsoft.Android.Sdk*.nupkg` file, as it is an assembly dependency
of `generator.dll`.  (Not sure why this didn't previously fail…)

Finally, add a new `$(_UseLegacyJavadocImport)` MSBuild property
which *disables* use of `java-source-utils.jar` for Javadoc importing,
and instead use the previous, legacy, doesn't work on JDK 11,
approach of using `javadoc` and HTML parsing.  This shouldn't be
needed, but just in case it *is* needed…

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Dec 11, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

For .NET 6 ("One .NET") integration purposes, provide a default item
group of `@(JavaSourceJar)` which includes `**\*-source?.jar` and
`**\*-src.jar`.  This will allow `dotnet build` of an "Android Java
Library Binding" project (`dotnet new android-bindinglib`) to
automatically process `.java` source code for documentation
translation purposes.

Add `Java.Interop.Tools.Generator.dll` to the
`Microsoft.Android.Sdk*.nupkg` file, as it is an assembly dependency
of `generator.dll`.  (Not sure why this didn't previously fail…)

Finally, add a new `$(_UseLegacyJavadocImport)` MSBuild property
which *disables* use of `java-source-utils.jar` for Javadoc importing,
and instead use the previous, legacy, doesn't work on JDK 11,
approach of using `javadoc` and HTML parsing.  This shouldn't be
needed, but just in case it *is* needed…

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Dec 11, 2020
Fixes: dotnet#4789

Context: dotnet/java-interop#687
Context: dotnet#5200

What do we want?  Updated documentation!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`].
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Finally, commit 380e95e, which added support for JDK 11, *broke*
support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's
Javadoc HTML output differs from what we expect.  With the new
`java-source-utils.jar` and
`generator --with-javadoc-xml=FILE` infrastructure in place, we can
reasonably address this breakage under JDK 11, fixing Issue dotnet#4789:

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

For .NET 6 ("One .NET") integration purposes, provide a default item
group of `@(JavaSourceJar)` which includes `**\*-source?.jar` and
`**\*-src.jar`.  This will allow `dotnet build` of an "Android Java
Library Binding" project (`dotnet new android-bindinglib`) to
automatically process `.java` source code for documentation
translation purposes.

Add `Java.Interop.Tools.Generator.dll` to the
`Microsoft.Android.Sdk*.nupkg` file, as it is an assembly dependency
of `generator.dll`.  (Not sure why this didn't previously fail…)

Finally, add a new `$(_UseLegacyJavadocImport)` MSBuild property
which *disables* use of `java-source-utils.jar` for Javadoc importing,
and instead use the previous, legacy, doesn't work on JDK 11,
approach of using `javadoc` and HTML parsing.  This shouldn't be
needed, but just in case it *is* needed…

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
jonpryor added a commit to dotnet/java-interop that referenced this issue Jan 4, 2021
Fixes: #642

Context: dotnet/android#4789
Context: dotnet/android#5200

Commit 69e1b80 added `tools/java-source-utils`, which along with
b588ef5, can parse Java source code and extract Javadoc comments
from Android API-30 sources into an XML file:
into an XML file:

        # API-30 `sources` package contains both `Object.java` and `Object.annotated.java`;
        # Skip the `.annotated.java` files
        $ find $HOME/android-toolchain/sdk/platforms/android-30/src/{android,java,javax,org} -iname \*.java \
                | grep -v '\.annotated\.' > sources.txt
        $ java -jar java-source-utils.jar -v \
                --source "$HOME/android-toolchain/sdk/platforms/android-30/src" \
                --output-javadoc android-javadoc.xml \
                @sources.txt

What can we *do* with the generated `android-javadoc.xml`?

`android-javadoc.xml` contains parameter names, and thus can be used
with `class-parse --docspath`; see commit 806082f.

What we *really* want to do is make the Javadoc information *useful*
to consumers of the binding assembly.  This means that we want a
C# XML Documentation file for the binding assembly.

The most straightforward way to get a C# XML Documentation File is to
emit [C# XML Documentation Comments][0] into the binding source code!

Add a new `generator --with-javadoc-xml=FILE` option.  When specified,
`FILE` will be treated as an XML file containing the output from
`java-source-utils.jar --output-javadoc` (69e1b80), and all
`<javadoc/>` elements within the XML file will be associated with C#
types and members to emit, based on the `//@jni-signature` and
`//@name` attributes, as appropriate.

When the bindings are written to disk, the Javadoc comments will be
translated to C# XML Documentation comments, in a "best effort" basis.
(THIS WILL BE INCOMPLETE.)

To perform the Javadoc-to-C# XML Documentation comments conversion,
add a new Irony-based grammar to `Java.Interop.Tools.JavaSource.dll`,
in the new `Java.Interop.Tools.JavaSource.SourceJavadocToXmldocParser`
type, which parses the Javadoc content and translates to XML.

In addition to transforming the Javadoc comments into C# XML
documentation comments, we *also* want to provide "upstream
information" in the form of:

 1. A URL to the corresponding online Javadoc HTML documentation.
 2. A copyright notice disclaimer.

Allow provision of this information by updating
`java-source-utils.jar` to support the new options:

        --doc-copyright FILE   Copyright information for Javadoc.  Should be in
                                 mdoc(5) XML, to be held within <remarks/>.
                                 Stored in //javadoc-metadata/copyright.
        --doc-url-prefix URL   Base URL for links to documentation.
                                 Stored in //javadoc-metadata/link/@Prefix.
        --doc-url-style STYLE  STYLE of URLs to generate for member links.
                                 Stored in //javadoc-metadata/link/@Style.
                                 Supported styles include:
                                 - developer.android.com/reference@2020-Nov

The new `/api/javadoc-metadata/link@prefix` and
`/api/javadoc-metadata/link@style` XML attributes, stored within
`java-source-utils.jar --output-javadoc` XML output, allow
construction of a URL to the Java member.

For example, given:

        java -jar java-source-utils.jar \
                --doc-url-prefix https://developer.android.com/reference \
                --doc-url-style developer.android.com/reference@2020-Nov

Then `generator` can emit the C# documentation comment for
`java.lang.Object.equals(Object)`:

        /// <format type="text/html">
        ///   <a href="https://developer.android.com/reference/java/lang/Object#equals(java.lang.Object)">Java documentation for <tt>java.lang.Object.equals(java.lang.Object)</tt>.</a>
        /// </format>

The copyright notice disclaimer is supported by
`java-source-utils.jar --doc-copyright FILE`; the contents of `FILE`
are inserted into the `/api/javadoc-metadata/copyright` element, and
will be copied into the output of every C# XML documentation block.

Example output is at:

  * <https://gist.github.com/jonpryor/004f01f4cd5ff32299ff590ba7a2fe0e>

Unfortunately, converting Javadoc to C# XML Documentation Comments is
not a "zero cost" operation.  Add a new
`generator --doc-comment-verbosity=STYLE` option to control how
"complete" the generated documentation comments are:

        --doc-comment-verbosity=STYLE
                               STYLE of C# documentation comments to emit.
                                 Defaults to `full`.  STYLE may be:
                                   * `intellisense`: emit <summary>, <param>,
                                     <returns>, <exception>.
                                   * `full`: plus <remarks>, <altmember>, ...

Using `--doc-comment-verbosity=full` will *most* impact build times.

TODO:

  * `SourceJavadocToXmldocParser` doesn't support many constructs.

[0]: https://docs.microsoft.com/en-us/dotnet/csharp/codedoc
jonpryor added a commit that referenced this issue Jan 6, 2021
…5253)

Fixes: #4789

Context: dotnet/java-interop@7574f16
Context: #5200

What do we want?  Updated documentation!  Better Bindings!

How do we get that?  Uh…

Historically, [Xamarin.Android API docs][0] were produced by parsing
Android's HTML documentation from `docs-24_r01.zip` and converting it
into [**mdoc**(5) documentation][1] via `tools/javadoc2mdoc`.
The problem is that Google hasn't released an updated `docs*.zip`
package since API-24 (~6 years ago), and thus our documentation is
woefully out of date.

We could have scraped developer.android.com/reference within that
time frame, but web scraping is annoying, and we'd still have to deal
with the pain of parsing HTML.

There is an alternative, though: with API-30, there is a new `sources`
package which contains the Java source code used for the API level,
which in turn contains Javadoc source code comments.  Previous API
levels similarly contained an `android-stubs-src.jar` file which
likewise contained Java source code containing Javadoc comments.

The new approach is to:

 1. Update `build-tools/xaprepare` to install the `sources` package.

 2. Use [`java-source-tool.jar`][2] to parse the Java source code,
    creating an `android-javadoc.xml` file.

 3. [Update `generator`][3] to consume `android-javadoc.xml` and
    convert the Javadocs into [C# XML documentation comments][4].

 4. Update `src/Mono.Android` so that `generator` will emit
    C# XML doc comments, and then produce a `Mono.Android.xml` file.

The result is a `Mono.Android.xml` file which contains imported
Android Javadoc documentation, e.g.

	<doc>
	  <assembly><name>Mono.Android</name></assembly>
	  <members>
	    <member name="T:Java.Lang.Object">
	      <summary>Class <c>Object</c> is the root of the class hierarchy.</summary>
	      <remarks>
	        <para>Class <c>Object</c> is the root of the class hierarchy.
	…

"Later", `Mono.Android.xml` can then be used alongside
[`mdoc update --import=Mono.Android.xml`][5] to update our published
API documentation.

Generation of `Mono.Android.xml` is disabled by default on CI PR
builds, as generating `Mono.Android.xml` increases `src/Mono.Android`
build times by an unacceptable amount.

With the inclusion of `java-source-tools.jar`, we can now fix the
TODO mentioned in commit 380e95e, and re-add support for
`@(JavaSourceJar)` when running under JDK 11.

Update `Xamarin.Android.Bindings.Core.targets` so that before
invoking `generator`, we first run `java-source-utils.jar` on the
`@(JavaSourceJar)` files, producing Javadoc XML files.
The `<BindingsGenerator/>` task in turn is updated to accept a new
`BindingsGenerator.JavadocXml` property, which is converted into a
`generator --with-javadoc-xml=FILE` option.

The `@(JavaSourceJar)` item group is "extended" to support the
following item metadata:

  * `%(CopyrightFile)`: A path to a file that contains copyright
    information for the Javadoc contents, which will be appended to
	all imported documentation.

  * `%(UrlPrefix)`: A URL prefix to support linking to online
    documentation within imported documentation.

  * `%(UrlStyle)`: The "style" of URLs to generate when linking to
    online documentation.  Only one style is currently supported:
    `developer.android.com/reference@2020-Nov`.

For .NET 6 ("One .NET") integration purposes, provide a default item
group of `@(JavaSourceJar)` which includes `**\*-source*.jar` and
`**\*-src.jar`.  This will allow `dotnet build` of an "Android Java
Library Binding" project (`dotnet new android-bindinglib`) to
automatically process `.java` source code for documentation
translation purposes.

Add a new `$(AndroidJavadocVerbosity)` MSBuild property, which
controls "how much" of the Javadoc comments are converted into C#
XML documentation.  Supported values are:

  * `full`: Convert as much Javadoc as possible.
  * `intellisense`: Only emit XML documentation for IDE-useful
    constructs: summary, parameters, returns, exceptions.

The difference between the two is *build time* impact: `full` takes
longer, and thus may not always be desirable.

Finally, add a new `$(_UseLegacyJavadocImport)` MSBuild property
which *disables* use of `java-source-utils.jar` for Javadoc importing,
and instead use the previous, legacy, doesn't work on JDK 11,
approach of using `javadoc` and HTML parsing.  This shouldn't be
needed, but just in case it *is* needed…

[0]: https://github.com/xamarin/android-api-docs
[1]: http://docs.go-mono.com/?link=man%3amdoc(5)
[2]: dotnet/java-interop@69e1b80
[3]: dotnet/java-interop#687
[4]: https://docs.microsoft.com/dotnet/csharp/codedoc
[5]: http://docs.go-mono.com/?link=man%3amdoc-update(1)
@ghost ghost locked as resolved and limited conversation to collaborators Jun 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: Bindings Issues in Java Library Binding projects.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants