diff --git a/Documentation/release-notes/6084.md b/Documentation/release-notes/6084.md new file mode 100644 index 00000000000..3ac01c37505 --- /dev/null +++ b/Documentation/release-notes/6084.md @@ -0,0 +1,8 @@ +#### Application build and deployment + +- [GitHub Pull Request #6084](https://github.com/xamarin/xamarin-android/pull/6084): + Android API 31 and a `$(TargetFrameworkVersion)` of `v11.0.99` + requires JDK 11. This can be obtained manually by installing + [Microsoft OpenJDK 11][ms-openjdk]. + +[ms-openjdk]: https://docs.microsoft.com/java/openjdk/download \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets index b06d444b8ff..7ac2650b877 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.Tooling.targets @@ -23,6 +23,7 @@ called for "legacy" projects in Xamarin.Android.Legacy.targets. JavaSdkPath="$(_JavaSdkDirectory)" JavaToolExe="$(JavaToolExe)" JavacToolExe="$(JavacToolExe)" + TargetPlatformVersion="$(TargetPlatformVersion)" LatestSupportedJavaVersion="$(LatestSupportedJavaVersion)" MinimumSupportedJavaVersion="$(MinimumSupportedJavaVersion)"> diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs index 2494270e4d7..76c60f021f3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Legacy/ValidateJavaVersion.cs @@ -50,13 +50,8 @@ protected override bool ValidateJava (string javaExe, Regex versionRegex) Version GetJavaVersionForFramework () { var apiLevel = MonoAndroidHelper.SupportedVersions.GetApiLevelFromFrameworkVersion (TargetFrameworkVersion); - if (apiLevel >= 30) { - // At present, it *looks like* API-R works with Build-tools r29, but - // historically API-X requires Build-tools rX, so if/when API-30 - // requires Build-tools r30, it will require JDK11. - // return new Version (11, 0); - return new Version (1, 8); - } + if (apiLevel >= 31) + return new Version (11, 0); if (apiLevel >= 24) return new Version (1, 8); else if (apiLevel == 23) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs b/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs index 7d42a5c328d..b8be0d2857d 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/ValidateJavaVersion.cs @@ -21,6 +21,8 @@ public class ValidateJavaVersion : AndroidTask public string JavacToolExe { get; set; } + public string TargetPlatformVersion { get; set; } + [Required] public string LatestSupportedJavaVersion { get; set; } @@ -67,6 +69,9 @@ bool ValidateJava () protected virtual bool ValidateJava (string javaExe, Regex versionRegex) { var required = Version.Parse (MinimumSupportedJavaVersion); + if (Version.TryParse (TargetPlatformVersion, out var targetPlatformVersion) && targetPlatformVersion.Major >= 31) { + required = new Version (11, 0); + } MinimumRequiredJdkVersion = required.ToString (); try { diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 2d8b746354d..c53e2366002 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -48,6 +48,8 @@ public static string [] SupportedTargetFrameworks () [Test] public void BuildBasicApplication ([ValueSource (nameof (SupportedTargetFrameworks))] string tfv, [Values (true, false)] bool isRelease) { + AssertTargetFrameworkVersionSupported (tfv); + var proj = new XamarinAndroidApplicationProject { IsRelease = isRelease, TargetFrameworkVersion = tfv, @@ -1143,8 +1145,6 @@ public void BuildMultiDexApplication ([Values ("dx", "d8")] string dexTool) } using (var b = CreateApkBuilder (Path.Combine ("temp", TestName), false, false)) { - proj.TargetFrameworkVersion = b.LatestTargetFrameworkVersion (); - string intermediateDir; if (IsWindows && !Builder.UseDotNet) { intermediateDir = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, proj.TargetFrameworkAbbreviated); @@ -2348,11 +2348,13 @@ public void CheckTargetFrameworkVersion ([Values (true, false)] bool isRelease) proj.SetProperty ("AndroidUseLatestPlatformSdk", "False"); using (var builder = CreateApkBuilder ()) { builder.GetTargetFrameworkVersionRange (out var _, out string firstFrameworkVersion, out var _, out string lastFrameworkVersion, out string[] _); + AssertTargetFrameworkVersionSupported (firstFrameworkVersion); proj.SetProperty ("TargetFrameworkVersion", firstFrameworkVersion); if (!Directory.Exists (Path.Combine (builder.FrameworkLibDirectory, firstFrameworkVersion))) Assert.Ignore ("This is a Pull Request Build. Ignoring test."); Assert.IsTrue (builder.Build (proj), "Build should have succeeded."); Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, $"Output Property: TargetFrameworkVersion={firstFrameworkVersion}"), $"TargetFrameworkVerson should be {firstFrameworkVersion}"); + AssertTargetFrameworkVersionSupported (lastFrameworkVersion); Assert.IsTrue (builder.Build (proj, parameters: new [] { $"TargetFrameworkVersion={lastFrameworkVersion}" }), "Build should have succeeded."); Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, $"Output Property: TargetFrameworkVersion={lastFrameworkVersion}"), $"TargetFrameworkVersion should be {lastFrameworkVersion}"); } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs index 718f4df238f..8a73f093a94 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/CodeBehindTests.cs @@ -478,8 +478,6 @@ string[] GetBuildProperties (LocalBuilder builder, bool manyBuild, bool dtbBuild var ret = new List { "AndroidGenerateLayoutBindings=true" }; - if (!Builder.UseDotNet) - ret.Add ("TargetFrameworkVersion=" + builder.LatestTargetFrameworkVersion ()); if (manyBuild) ret.Add ("ForceParallelBuild=true"); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs index 394d6d3f1b1..5018a1c02f0 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ResolveSdksTaskTests.cs @@ -21,7 +21,10 @@ public class ResolveSdksTaskTests : BaseTest { new ApiInfo () { Id = "25", Level = 25, Name = "Nougat", FrameworkVersion = "v7.1", Stable = true }, new ApiInfo () { Id = "26", Level = 26, Name = "Oreo", FrameworkVersion = "v8.0", Stable = true }, new ApiInfo () { Id = "27", Level = 27, Name = "Oreo", FrameworkVersion = "v8.1", Stable = true }, - new ApiInfo () { Id = "P", Level = 28, Name = "P", FrameworkVersion = "v8.99", Stable = false }, + new ApiInfo () { Id = "28", Level = 28, Name = "Pie", FrameworkVersion = "v9.0", Stable = false }, + new ApiInfo () { Id = "29", Level = 29, Name = "Android10", FrameworkVersion = "v10.0", Stable = false }, + new ApiInfo () { Id = "30", Level = 30, Name = "Android11", FrameworkVersion = "v11.0", Stable = false }, + new ApiInfo () { Id = "S", Level = 31, Name = "S", FrameworkVersion = "v11.0.99", Stable = false }, new ApiInfo () { Id = "Z", Level = 127, Name = "Z", FrameworkVersion = "v108.1.99", Stable = false }, }; @@ -35,9 +38,9 @@ public class ResolveSdksTaskTests : BaseTest { /* jdk */ "1.8.0", /* apis*/ apiInfoSelection, /* useLatestAndroidSdk */ true, - /* targetFrameworkVersion */ "v8.99", + /* targetFrameworkVersion */ "v9.0", /* expectedTaskResult */ true, - /* expectedTargetFramework */ "v8.99", + /* expectedTargetFramework */ "v9.0", /* expectedError */ "", /* expectedErrorMessage */ "", }, @@ -101,9 +104,9 @@ public class ResolveSdksTaskTests : BaseTest { /* jdk */ "1.8.0", /* apis*/ apiInfoSelection, /* useLatestAndroidSdk */ false, - /* targetFrameworkVersion */ "v8.99", + /* targetFrameworkVersion */ "v9.0", /* expectedTaskResult */ true, - /* expectedTargetFramework */ "v8.99", + /* expectedTargetFramework */ "v9.0", /* expectedError */ "", /* expectedErrorMessage */ "", }, @@ -151,6 +154,17 @@ public class ResolveSdksTaskTests : BaseTest { /* expectedError */ "XA0001", /* expectedErrorMessage */ "Unsupported or invalid $(TargetFrameworkVersion) value of 'v6.0'. Please update your Project Options.", }, + new object[] { + /* buildtools */ "30.0.0", + /* jdk */ "11.0", + /* apis*/ apiInfoSelection, + /* useLatestAndroidSdk */ false, + /* targetFrameworkVersion */ "v11.0.99", + /* expectedTaskResult */ true, + /* expectedTargetFramework */ "v11.0.99", + /* expectedError */ "", + /* expectedErrorMessage */ "", + }, }; #pragma warning restore 414 [Test] @@ -184,7 +198,7 @@ public void UseLatestAndroidSdk (string buildtools, string jdk, ApiInfo[] apis, JavaSdkPath = javaPath, JavaToolExe = javaExe, JavacToolExe = javacExe, - LatestSupportedJavaVersion = "1.8.0", + LatestSupportedJavaVersion = LatestSupportedJavaVersion, MinimumSupportedJavaVersion = "1.7.0", }; var androidTooling = new ResolveAndroidTooling { @@ -429,6 +443,7 @@ public void LatestTFV_OldTargetSdkVersion () proj.TargetSdkVersion = "19"; using (var b = CreateApkBuilder ()) { proj.TargetFrameworkVersion = b.LatestTargetFrameworkVersion (); + AssertTargetFrameworkVersionSupported (proj.TargetFrameworkVersion); Assert.IsTrue (b.Build (proj), "Build should have succeeded."); } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs index 1c3fb61229d..f4073426fa3 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/BaseTest.cs @@ -212,6 +212,16 @@ protected static void AssertLLVMSupported (bool llvm) } } + protected static void AssertTargetFrameworkVersionSupported (string targetFrameworkVersion) + { + if (Builder.UseDotNet) + return; // N/A in .NET 6 + if (!Version.TryParse (targetFrameworkVersion.TrimStart ('v'), out var version) || version <= new Version (11, 0)) + return; // TFV is 11.0 or less + if (!TestEnvironment.IsUsingJdk11) + Assert.Ignore ("Test is only supported when using JDK 11."); + } + protected static void WaitFor(int milliseconds) { var pause = new ManualResetEvent(false); 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 b4a4befa793..a3e26dbbd74 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 @@ -581,7 +581,7 @@ public void XamarinLegacySdk () using var b = new Builder (); var dotnetTargetFramework = "net6.0-android30.0"; - var legacyTargetFrameworkVersion = b.LatestTargetFrameworkVersion ().TrimStart ('v'); + var legacyTargetFrameworkVersion = "11.0"; var legacyTargetFramework = $"monoandroid{legacyTargetFrameworkVersion}"; proj.SetProperty ("TargetFramework", value: ""); proj.SetProperty ("TargetFrameworks", value: $"{dotnetTargetFramework};{legacyTargetFramework}"); diff --git a/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs b/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs index f22aaa95b17..2ed567d90a3 100755 --- a/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs +++ b/tests/MSBuildDeviceIntegration/Tests/DebuggingTest.cs @@ -32,6 +32,8 @@ void SetTargetFrameworkAndManifest(XamarinAndroidApplicationProject proj, Builde proj.TargetFrameworkVersion = "v11.0"; } + AssertTargetFrameworkVersionSupported (proj.TargetFrameworkVersion); + proj.AndroidManifest = $@"