diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 0f81bf9e1ef..7738de720d1 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -298,6 +298,22 @@ such as ``: ``` +## JavaDocJar + +In a Xamarin.Android binding project, the **JavaDocJar** build action +is used on `.jar` files which contain *Javadoc HTML*. The Javadoc HTML +is parsed in order to extract parameter names. + +Only certain "Javadoc HTML dialects" are supported, including: + + * JDK 1.7 `javadoc` output + * JDK 1.8 `javadoc` output + * Droiddoc output + +This build action is deprecated in Xamarin.Android 11.3, and will not be +supported in .NET 6. +The `@(JavaSourceJar)` build action should be preferred. + ## JavaSourceJar In a Xamarin.Android binding project, the **JavaSourceJar** build action diff --git a/Documentation/release-notes/5479.md b/Documentation/release-notes/5479.md new file mode 100644 index 00000000000..2d1833cae7b --- /dev/null +++ b/Documentation/release-notes/5479.md @@ -0,0 +1,10 @@ +### Issues fixed + + * [GitHub 2745](https://github.com/xamarin/xamarin-android/issues/2745): + The `@(JavaDocJar)` build action would either cause an MSB3375 error, + or wasn't used at all. + +#### Deprecation of JavaDocJar Build action in favor of JavaSourceJar + +The `@(JavaDocJar)` Build action is deprecated, and will not work in .NET 6. +Please use the `@(JavaSourceJar)` build action. diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets index be335ee74e5..3f1b604dcd6 100644 --- a/build-tools/installers/create-installers.targets +++ b/build-tools/installers/create-installers.targets @@ -239,7 +239,7 @@ <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Bindings.targets" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Bindings.ClassParse.targets" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Bindings.Core.targets" /> - <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Bindings.Documentation.targets" /> + <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Bindings.Documentation.targets" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Bindings.JarToXml.targets" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Build.Tasks.dll" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Build.Tasks.pdb" /> 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 4c66ae634b2..7b96ac490e1 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 @@ -17,14 +17,13 @@ This file is only used by binding projects. .NET 5 can eventually use it, once ` - + 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 4b2ab09b74c..aed17405ea6 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 @@ -437,6 +437,30 @@ public void RemoveEventHandlerResolution () } } + [Test] + [Category ("DotNetIgnore")] + public void JavaDocJar () + { + var binding = new XamarinAndroidBindingProject () { + AndroidClassParser = "class-parse", + }; + binding.SetProperty ("DocumentationFile", "UnnamedProject.xml"); + using (var bindingBuilder = CreateDllBuilder ()) { + binding.Jars.Add (new AndroidItem.EmbeddedJar ("javasourcejartest.jar") { + BinaryContent = () => ResourceData.JavaSourceJarTestJar, + }); + binding.OtherBuildItems.Add (new BuildItem ("JavaDocJar", "javasourcejartest-javadoc.jar") { + BinaryContent = () => ResourceData.JavaSourceJarTestJavadocJar, + }); + Assert.IsTrue (bindingBuilder.Build (binding), "binding build should have succeeded"); + + var cs_file = bindingBuilder.Output.GetIntermediaryPath ( + Path.Combine ("generated", "src", "Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest.cs")); + FileAssert.Exists (cs_file); + StringAssert.Contains ("Greet (string name, global::Java.Util.Date date)", File.ReadAllText (cs_file)); + } + } + [Test] public void JavaSourceJar () { @@ -446,10 +470,10 @@ public void JavaSourceJar () binding.SetProperty ("DocumentationFile", "UnnamedProject.xml"); using (var bindingBuilder = CreateDllBuilder ()) { binding.Jars.Add (new AndroidItem.EmbeddedJar ("javasourcejartest.jar") { - BinaryContent = () => Convert.FromBase64String (InlineData.JavaClassesJarBase64) + BinaryContent = () => ResourceData.JavaSourceJarTestJar, }); binding.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasourcejartest-sources.jar") { - BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) + BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); Assert.IsTrue (bindingBuilder.Build (binding), "binding build should have succeeded"); @@ -496,7 +520,7 @@ public void NullableReferenceTypes (string classParser) AndroidClassParser = classParser, Jars = { new AndroidItem.EmbeddedJar ("foo.jar") { - BinaryContent = () => Convert.FromBase64String (InlineData.JavaClassesJarBase64), + BinaryContent = () => ResourceData.JavaSourceJarTestJar, } } }; diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Directory.Build.targets b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Directory.Build.targets new file mode 100644 index 00000000000..6194f3095cc --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Directory.Build.targets @@ -0,0 +1,54 @@ + + + + + + + + + + + + <_SourceVersions>-source $(JavacSourceVersion) -target $(JavacTargetVersion) + <_Outdir>$(IntermediateOutputPath)/classes + + + + + + + + + + + + + + <_Javadoc>"$(Java8SdkDirectory)/bin/javadoc" + <_Outdir>$(IntermediateOutputPath)/javadoc + + + + + + + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest-javadoc.jar b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest-javadoc.jar new file mode 100644 index 00000000000..4eadc3f4db9 Binary files /dev/null and b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest-javadoc.jar differ diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest-sources.jar b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest-sources.jar new file mode 100644 index 00000000000..456b53d3525 Binary files /dev/null and b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest-sources.jar differ diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest.jar b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest.jar new file mode 100644 index 00000000000..fe7ba83bf2a Binary files /dev/null and b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Resources/javasourcejartest.jar differ diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs index 48993402753..00b73baf9d3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/InlineData.cs @@ -8,61 +8,6 @@ namespace Xamarin.Android.Build.Tests { static class InlineData { -#if false // Java source with javadoc - package com.xamarin.android.test.msbuildtest; - - public class JavaSourceJarTest - { - /** - * Returns greeting message. - *

- * Returns "Morning, ", "Hello, " or "Evening, " with name argument, - * depending on the argument hour. - *

- * @param name name to display. - * @param date time to determine the greeting message. - * @return the resulting message. - */ - public String greet (String name, java.util.Date date) - { - String head = date.getHours () < 11 ? "Morning, " : date.getHours () < 17 ? "Hello, " : "Evening, "; - return head + name; - } - } -#endif - - public const string JavaSourcesJarBase64 = @" -UEsDBBQACAgIAC2gP0wAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMAUEsHCAAAAAACAAAAAAAAAFBLAwQUAAgIC -AAtoD9MAAAAAAAAAAAAAAAAFAAAAE1FVEEtSU5GL01BTklGRVNULk1G803My0xLLS7RDUstKs7Mz7NSMNQz4OVyLkpNLE -lN0XWqBAlY6BnEG5oaKmj4FyUm56QqOOcXFeQXJZYA1WvycvFyAQBQSwcIlldz8EQAAABFAAAAUEsDBBQACAgIACqgP0w -AAAAAAAAAAAAAAAA7AAAAY29tL3hhbWFyaW4vYW5kcm9pZC90ZXN0L21zYnVpbGR0ZXN0L0phdmFTb3VyY2VKYXJUZXN0 -LmphdmF1kc1uwjAMx+99CosTsCqI0yRgG4dNQki7jL2Aaaw2Wz4qJ2WbJt59SSgfQsyq4kb+2X/babH6xJqgckZ8o0FWV -qCV7JQUgXwQxm87pWX6nxdF2221qqDS6D2scYcb13FFa+T3CBS/BUSbjMfZwxjeKHRsPdRMFJStwZD3UU8cgUX7eM0OXh -3byJYwiN+KtHbRg2MYvOyoj8CXCg1YNATIdWfIhvJYSFJLViY1ZyE0ZwKa2O1ZenLWXrbIaA718hEcSOVbjT/iipEYYlj -1DAVioyxlnX+nXHKeLUNMvtO3qEn2/YY3gROSK8Kwv6XOSviIaxddUFo8p1ZSP6Oceth+sp5vCCU8ZELUFFZxeg/DESxg -OoWny0XD7JSb7FbGfco4vcbs8jHmp+R+zix8l/s9xPbFvvgDUEsHCDlC8jY2AQAAawIAAFBLAQIUABQACAgIAC2gP0wAA -AAAAgAAAAAAAAAJAAQAAAAAAAAAAAAAAAAAAABNRVRBLUlORi/+ygAAUEsBAhQAFAAICAgALaA/TJZXc/BEAAAARQAAAB -QAAAAAAAAAAAAAAAAAPQAAAE1FVEEtSU5GL01BTklGRVNULk1GUEsBAhQAFAAICAgAKqA/TDlC8jY2AQAAawIAADsAAAA -AAAAAAAAAAAAAwwAAAGNvbS94YW1hcmluL2FuZHJvaWQvdGVzdC9tc2J1aWxkdGVzdC9KYXZhU291cmNlSmFyVGVzdC5q -YXZhUEsFBgAAAAADAAMA5gAAAGICAAAAAA=="; - - public const string JavaClassesJarBase64 = @" -UEsDBBQACAgIAO+EP0wAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMAUEsHCAAAAAACAAAAAAAAAFBLAwQUAAgIC -ADvhD9MAAAAAAAAAAAAAAAAFAAAAE1FVEEtSU5GL01BTklGRVNULk1G803My0xLLS7RDUstKs7Mz7NSMNQz4OVyLkpNLE -lN0XWqBAlY6BnEG5oaKmj4FyUm56QqOOcXFeQXJZYA1WvycvFyAQBQSwcIlldz8EQAAABFAAAAUEsDBBQACAgIALOEP0w -AAAAAAAAAAAAAAAA8AAAAY29tL3hhbWFyaW4vYW5kcm9pZC90ZXN0L21zYnVpbGR0ZXN0L0phdmFTb3VyY2VKYXJUZXN0 -LmNsYXNzbVHZSsNAFD1j2yStaW3rvlvX1i0g4osiuKLi8lARfHPaDCWaJiWdit/ji6/6UkHBD/CjxDupIloDucuZO+fMn -Hn/eHkDsIpCAp3oS6AfAwYGDQwZGNYxkoCmUA2jKozpGNcxwaBtOJ4jNxki+cIFQ3THtwVD17HjidNGtSSCc15yCYlVAi -Ekw1r++JrfcsvlXsUqysDxKustpCEd19rlUqwX2kcYkkXJyzcnvBYS6sgxJIp+IyiLfUcJ9B3RnhZwxINzUZfLisWEiaS -OSRNTmGaIn/iBR4SLdHT9QLiur6r43q34Rvv/am83HNcWgYkZzJqYQ54uUfar1h2vclq3uGcHvmNbkiStar2kxsO67UAM -6R/ys9K1KP+GWnoMqd9+MBgVIQ+IqR7afEiu81pNeDbD0j92ttv3dQVy0ZD+t0pP/h+fkYN6fvV1gCnvKKaoG6XMKMfmn -8GeqKBHpqiFYIRiGpmv0SvaGqW8sthER7rzHkY28oDusMuoLvqAWDZ2+grt8hn6UhPGAv1NxB9DWcWbIk4QYxeyGEc3Rc -BAJJXc0qmjw4eTvZ9QSwcINzBZxakBAAC1AgAAUEsBAhQAFAAICAgA74Q/TAAAAAACAAAAAAAAAAkABAAAAAAAAAAAAAA -AAAAAAE1FVEEtSU5GL/7KAABQSwECFAAUAAgICADvhD9Mlldz8EQAAABFAAAAFAAAAAAAAAAAAAAAAAA9AAAATUVUQS1J -TkYvTUFOSUZFU1QuTUZQSwECFAAUAAgICACzhD9MNzBZxakBAAC1AgAAPAAAAAAAAAAAAAAAAADDAAAAY29tL3hhbWFya -W4vYW5kcm9pZC90ZXN0L21zYnVpbGR0ZXN0L0phdmFTb3VyY2VKYXJUZXN0LmNsYXNzUEsFBgAAAAADAAMA5wAAANYCAA -AAAA=="; - const string Resx = @" diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs new file mode 100644 index 00000000000..8f88d205e02 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/ResourceData.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Xamarin.Android.Build.Tests +{ + static class ResourceData + { + static Lazy javaSourceJarTestJar = new Lazy(() => GetResourceData ("javasourcejartest.jar")); + static Lazy javaSourceJarTestSourcesJar = new Lazy(() => GetResourceData ("javasourcejartest-sources.jar")); + static Lazy javaSourceJarTestJavadocJar = new Lazy(() => GetResourceData ("javasourcejartest-javadoc.jar")); + + public static byte[] JavaSourceJarTestJar => javaSourceJarTestJar.Value; + public static byte[] JavaSourceJarTestSourcesJar => javaSourceJarTestSourcesJar.Value; + public static byte[] JavaSourceJarTestJavadocJar => javaSourceJarTestJavadocJar.Value; + + static byte[] GetResourceData (string name) + { + using var s = typeof (InlineData).Assembly.GetManifestResourceStream (name); + using var m = new MemoryStream (checked ((int) s.Length)); + s.CopyTo (m); + return m.ToArray (); + } + } +} diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs index 6be1f4fd113..e114a73f8ab 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs @@ -89,7 +89,7 @@ public void DotNetBuildLibrary (bool isRelease, bool duplicateAar) TextContent = () => $"{env_var}={env_val}", }); libB.OtherBuildItems.Add (new AndroidItem.AndroidLibrary ("sub\\directory\\foo.jar") { - BinaryContent = () => Convert.FromBase64String (InlineData.JavaClassesJarBase64), + BinaryContent = () => ResourceData.JavaSourceJarTestJar, }); libB.OtherBuildItems.Add (new AndroidItem.AndroidLibrary ("sub\\directory\\arm64-v8a\\libfoo.so") { BinaryContent = () => Array.Empty (), @@ -183,7 +183,7 @@ public void DotNetNew ([Values ("android", "androidlib", "android-bindinglib")] { var dotnet = CreateDotNetBuilder (); Assert.IsTrue (dotnet.New (template), $"`dotnet new {template}` should succeed"); - File.WriteAllBytes (Path.Combine (dotnet.ProjectDirectory, "foo.jar"), Convert.FromBase64String (InlineData.JavaClassesJarBase64)); + File.WriteAllBytes (Path.Combine (dotnet.ProjectDirectory, "foo.jar"), ResourceData.JavaSourceJarTestJar); Assert.IsTrue (dotnet.New ("android-activity"), "`dotnet new android-activity` should succeed"); Assert.IsTrue (dotnet.New ("android-layout", Path.Combine (dotnet.ProjectDirectory, "Resources", "layout")), "`dotnet new android-layout` should succeed"); Assert.IsTrue (dotnet.Build (), "`dotnet build` should succeed"); @@ -205,7 +205,7 @@ public void DotNetPack ([Values ("net6.0-android", "net6.0-android30")] string t BinaryContent = () => Array.Empty (), }); proj.OtherBuildItems.Add (new AndroidItem.AndroidLibrary ("sub\\directory\\foo.jar") { - BinaryContent = () => Convert.FromBase64String (InlineData.JavaClassesJarBase64), + BinaryContent = () => ResourceData.JavaSourceJarTestJar, }); proj.OtherBuildItems.Add (new AndroidItem.AndroidLibrary ("sub\\directory\\arm64-v8a\\libfoo.so") { BinaryContent = () => Array.Empty (), @@ -280,12 +280,11 @@ public void DotNetBuildBinding () ", }); proj.Sources.Add (new AndroidItem.AndroidLibrary ("javaclasses.jar") { - BinaryContent = () => Convert.FromBase64String (InlineData.JavaClassesJarBase64) + BinaryContent = () => ResourceData.JavaSourceJarTestJar, + }); + proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javaclasses-sources.jar") { + BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); - // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working - //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") { - // BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) - //}); var dotnet = CreateDotNetBuilder (proj); Assert.IsTrue (dotnet.Build (), "`dotnet build` should succeed"); @@ -350,12 +349,11 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease) } }; proj.OtherBuildItems.Add (new AndroidItem.InputJar ("javaclasses.jar") { - BinaryContent = () => Convert.FromBase64String (InlineData.JavaClassesJarBase64) + BinaryContent = () => ResourceData.JavaSourceJarTestJar, + }); + proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javaclasses-sources.jar") { + BinaryContent = () => ResourceData.JavaSourceJarTestSourcesJar, }); - // TODO: bring back when Xamarin.Android.Bindings.Documentation.targets is working - //proj.OtherBuildItems.Add (new BuildItem ("JavaSourceJar", "javasources.jar") { - // BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) - //}); if (!runtimeIdentifiers.Contains (";")) { proj.SetProperty (KnownProperties.RuntimeIdentifier, runtimeIdentifiers); } else { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj index 21a400a6568..a17bcf4e2c2 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Xamarin.Android.Build.Tests.csproj @@ -38,4 +38,16 @@ + + + javasourcejartest.jar + + + javasourcejartest-sources.jar + + + javasourcejartest-javadoc.jar + + + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/java/com/microsoft/android/test/msbuildtest/JavaSourceJarTest.java b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/java/com/microsoft/android/test/msbuildtest/JavaSourceJarTest.java new file mode 100644 index 00000000000..1d42690ced9 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/java/com/microsoft/android/test/msbuildtest/JavaSourceJarTest.java @@ -0,0 +1,20 @@ +package com.xamarin.android.test.msbuildtest; + +public class JavaSourceJarTest +{ + /** + * Returns greeting message. + *

+ * Returns "Morning, ", "Hello, " or "Evening, " with name argument, + * depending on the argument hour. + *

+ * @param name name to display. + * @param date time to determine the greeting message. + * @return the resulting message. + */ + public String greet (String name, java.util.Date date) + { + String head = date.getHours () < 11 ? "Morning, " : date.getHours () < 17 ? "Hello, " : "Evening, "; + return head + name; + } +}