From ace5169f6fec1b530396baf6aecdf54af62a3727 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Mon, 13 Jan 2025 10:41:33 -0500 Subject: [PATCH] [build] Support JDK-21 (#9672) * [build] Support JDK-21 Context: https://github.com/dotnet/android/pull/9651 PR #9651 demonstrated that it was fairly straightforward to use JDK-21 on CI. We don't want to fully bump to JDK-21, because we still support building with JDK-17, so we *at minimum* need to run tests on both JDK-17 and JDK-21. As a "minimal introductory step", add support for JDK-21: * Update to Gradle 8.12, for harmony with dotnet/java-interop. * Update the `` task to use `javac --release N` when using JDK-17 and later. JDK-11 doesn't support `javac --release`. (Why care about JDK-11? Because .NET 8 still supports it, and this will make future cherry-picking easier.) * Set `$(LatestSupportedJavaVersion)`=21.0.99, which removes the XA0030 error which would result from using JDK-21. * Update `tools/workload-dependencies` to use `$(LatestSupportedJavaVersion)` property, instead of always using `$(JavaSdkVersion)+1`. * Address comments. --- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../Android/Xamarin.Android.Javac.targets | 2 ++ .../Tasks/Javac.cs | 22 +++++++++++++++++-- .../Xamarin.Android.Common.props.in | 2 +- tools/workload-dependencies/Program.cs | 17 +++++++++++++- .../WorkloadDependencies.proj | 1 + 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/build-tools/gradle/gradle/wrapper/gradle-wrapper.properties b/build-tools/gradle/gradle/wrapper/gradle-wrapper.properties index d642e7f8f76..d6e308a6378 100644 --- a/build-tools/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/build-tools/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets index 0f05b9e1a0d..3de79d73919 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Javac.targets @@ -121,6 +121,7 @@ It is shared between "legacy" binding projects and .NET 7+ projects. Jars="@(_BindingJavaLibrariesToCompile);@(_ReferenceJavaLibs)" JavacTargetVersion="$(JavacTargetVersion)" JavacSourceVersion="$(JavacSourceVersion)" + JdkVersion="$(_JdkVersion)" IntermediateOutputPath="$(IntermediateOutputPath)" AssemblyIdentityMapFile="$(_AndroidLibrayProjectAssemblyMapFile)" /> @@ -168,6 +169,7 @@ It is shared between "legacy" binding projects and .NET 7+ projects. Jars="@(_JavaLibrariesToCompile);@(_ReferenceJavaLibs)" JavacTargetVersion="$(JavacTargetVersion)" JavacSourceVersion="$(JavacSourceVersion)" + JdkVersion="$(_JdkVersion)" IntermediateOutputPath="$(IntermediateOutputPath)" AssemblyIdentityMapFile="$(_AndroidLibrayProjectAssemblyMapFile)" /> diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs index b7df052a49f..74cbb16c6e4 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs @@ -27,6 +27,8 @@ public class Javac : JavaCompileToolTask public string JavacTargetVersion { get; set; } public string JavacSourceVersion { get; set; } + public string JdkVersion { get; set; } + public override string DefaultErrorCode => "JAVAC0000"; public override bool RunTask () @@ -61,12 +63,28 @@ protected override string GenerateCommandLineCommands () cmd.AppendSwitchIfNotNull ("-J-Dfile.encoding=", "UTF8"); cmd.AppendFileNameIfNotNull (string.Format ("@{0}", TemporarySourceListFile)); - cmd.AppendSwitchIfNotNull ("-target ", JavacTargetVersion); - cmd.AppendSwitchIfNotNull ("-source ", JavacSourceVersion); + + if (int.TryParse (JavacSourceVersion, out int sourceVersion) && + int.TryParse (JavacTargetVersion, out int targetVersion) && + JavacSupportsRelease ()) { + cmd.AppendSwitchIfNotNull ("--release ", Math.Max (sourceVersion, targetVersion).ToString ()); + } else { + cmd.AppendSwitchIfNotNull ("-target ", JavacTargetVersion); + cmd.AppendSwitchIfNotNull ("-source ", JavacSourceVersion); + } return cmd.ToString (); } + bool JavacSupportsRelease () + { + if (string.IsNullOrEmpty (JdkVersion)) { + return false; + } + var jdkVersion = Version.Parse (JdkVersion); + return jdkVersion.Major >= 17; + } + protected override void WriteOptionsToResponseFile (StreamWriter sw) { sw.WriteLine ($"-d \"{ClassesOutputDirectory.Replace (@"\", @"\\")}\""); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in index f1c5079ac8a..afad4ac5eda 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.props.in @@ -17,7 +17,7 @@ false true true - 17.0.99 + 21.0.99 {abi}{versionCode:D5} UpdateGeneratedFiles True diff --git a/tools/workload-dependencies/Program.cs b/tools/workload-dependencies/Program.cs index c61ab3b1d39..8b9a9712f10 100644 --- a/tools/workload-dependencies/Program.cs +++ b/tools/workload-dependencies/Program.cs @@ -14,6 +14,7 @@ var CmdlineToolsVersion = (string?) null; var BuildToolsVersion = (string?) null; var JdkVersion = (string?) null; +var JdkMaxVersion = (string?) null; var NdkVersion = (string?) null; var PlatformToolsVersion = (string?) null; var PlatformVersion = (string?) null; @@ -37,6 +38,9 @@ { "jdk-version=", "The JDK {VERSION} dotnet/android is built against.", v => JdkVersion = v }, + { "jdk-max-version=", + "The maximum JDK {VERSION} dotnet/android supports.", + v => JdkMaxVersion = v }, { "ndk-version=", "The Android NDK {VERSION} dotnet/android is built against.", v => NdkVersion = v }, @@ -160,7 +164,7 @@ JProperty CreateJdkProperty (XDocument doc) { var v = new Version (JdkVersion ?? "17.0"); var start = new Version (v.Major, v.Minor); - var end = new Version (v.Major+1, 0); + var end = GetMaxJdkVersion (v); var latestRevision = JdkVersion ?? GetLatestRevision (doc, "jdk"); var contents = new JObject ( new JProperty ("version", $"[{start},{end})")); @@ -169,6 +173,17 @@ JProperty CreateJdkProperty (XDocument doc) return new JProperty ("jdk", contents); } +string GetMaxJdkVersion (Version v) +{ + if (!string.IsNullOrEmpty (JdkMaxVersion)) { + // JdkMaxVersion is `$(LatestSupportedJavaVersion)`, which is still a supported version! + // Return the major version past JdkMaxVersion + var x = new Version (JdkMaxVersion); + return new Version (x.Major+1, 0).ToString (); + } + return new Version (v.Major+1, 0).ToString (); +} + IEnumerable GetSupportedElements (XDocument doc, string element) { if (doc.Root == null) { diff --git a/tools/workload-dependencies/WorkloadDependencies.proj b/tools/workload-dependencies/WorkloadDependencies.proj index e8831e28a87..0429b1bf27b 100644 --- a/tools/workload-dependencies/WorkloadDependencies.proj +++ b/tools/workload-dependencies/WorkloadDependencies.proj @@ -68,6 +68,7 @@ <_WorkloadDeps Include="--build-tools-version=$(AndroidSdkBuildToolsVersion)" /> <_WorkloadDeps Include="--cmdline-tools-version=$(AndroidCommandLineToolsVersion)" /> <_WorkloadDeps Include="--jdk-version=$(JavaSdkVersion)" /> + <_WorkloadDeps Include="--jdk-max-version=$(LatestSupportedJavaVersion)" /> <_WorkloadDeps Include="--ndk-version=$(AndroidNdkVersion)" /> <_WorkloadDeps Include="--platform-tools-version=$(AndroidSdkPlatformToolsVersion)" /> <_WorkloadDeps Include="--platform-version=$(AndroidSdkPlatformVersion)" />