-
Notifications
You must be signed in to change notification settings - Fork 531
/
ValidateJavaVersion.cs
132 lines (111 loc) · 4.44 KB
/
ValidateJavaVersion.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Xamarin.Android.Tools;
using Microsoft.Android.Build.Tasks;
namespace Xamarin.Android.Tasks
{
/// <summary>
/// ValidateJavaVersion's job is to shell out to java and javac to detect their version
/// </summary>
public class ValidateJavaVersion : AndroidTask
{
public override string TaskPrefix => "VJV";
public string JavaSdkPath { get; set; }
public string JavaToolExe { get; set; }
public string JavacToolExe { get; set; }
public string TargetPlatformVersion { get; set; }
[Required]
public string LatestSupportedJavaVersion { get; set; }
[Required]
public string MinimumSupportedJavaVersion { get; set; }
[Output]
public string MinimumRequiredJdkVersion { get; set; }
[Output]
public string JdkVersion { get; set; }
public override bool RunTask ()
{
if (!ValidateJava ())
return false;
Log.LogDebugMessage ($"{nameof (ValidateJavaVersion)} Outputs:");
Log.LogDebugMessage ($" {nameof (JdkVersion)}: {JdkVersion}");
Log.LogDebugMessage ($" {nameof (MinimumRequiredJdkVersion)}: {MinimumRequiredJdkVersion}");
return !Log.HasLoggedErrors;
}
// `java -version` will produce values such as:
// java version "9.0.4"
// java version "1.8.0_77"
static readonly Regex JavaVersionRegex = new Regex (@"version ""(?<version>[\d\.]+)(_\d+)?[^""]*""");
// `javac -version` will produce values such as:
// javac 9.0.4
// javac 1.8.0_77
internal static readonly Regex JavacVersionRegex = new Regex (@"javac (?<version>\d+\.[\d\.]+)(_\d+)?");
bool ValidateJava ()
{
var java = JavaToolExe ?? (OS.IsWindows ? "java.exe" : "java");
var javac = JavacToolExe ?? (OS.IsWindows ? "javac.exe" : "javac");
return ValidateJava (java, JavaVersionRegex) &&
ValidateJava (javac, JavacVersionRegex);
}
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 {
var versionNumber = GetVersionFromTool (javaExe, versionRegex);
if (versionNumber != null) {
Log.LogMessage (MessageImportance.Normal, $"Found Java SDK version {versionNumber}.");
if (versionNumber < required) {
Log.LogCodedError ("XA0031", Properties.Resources.XA0031_NET, required);
}
var latest = Version.Parse (LatestSupportedJavaVersion);
if (versionNumber > latest) {
Log.LogCodedError ("XA0030", Properties.Resources.XA0030, versionNumber, latest.ToString (fieldCount: 2));
}
}
} catch (Exception ex) {
Log.LogWarningFromException (ex);
Log.LogCodedWarning ("XA0034", Properties.Resources.XA0034, required);
return false;
}
return !Log.HasLoggedErrors;
}
protected Version GetVersionFromTool (string javaExe, Regex versionRegex)
{
// NOTE: this doesn't need to use GetRegisteredTaskObjectAssemblyLocal()
// because the path to java/javac is the key and the value is a System.Version.
var javaTool = Path.Combine (JavaSdkPath, "bin", javaExe);
var key = new Tuple<string, string> (nameof (ValidateJavaVersion), javaTool);
var cached = BuildEngine4.GetRegisteredTaskObject (key, RegisteredTaskObjectLifetime.AppDomain) as Version;
if (cached != null) {
Log.LogDebugMessage ($"Using cached value for `{javaTool} -version`: {cached}");
JdkVersion = cached.ToString ();
return cached;
}
var sb = new StringBuilder ();
MonoAndroidHelper.RunProcess (javaTool, "-version", (s, e) => {
if (!string.IsNullOrEmpty (e.Data))
sb.AppendLine (e.Data);
}, (s, e) => {
if (!string.IsNullOrEmpty (e.Data))
sb.AppendLine (e.Data);
});
var versionInfo = sb.ToString ();
var versionNumberMatch = versionRegex.Match (versionInfo);
Version versionNumber;
if (versionNumberMatch.Success && Version.TryParse (versionNumberMatch.Groups ["version"]?.Value, out versionNumber)) {
BuildEngine4.RegisterTaskObject (key, versionNumber, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false);
JdkVersion = versionNumberMatch.Groups ["version"].Value;
return versionNumber;
} else {
Log.LogCodedWarning ("XA0033", Properties.Resources.XA0033, javaExe, versionInfo);
return null;
}
}
}
}