Skip to content

Commit 9b03310

Browse files
[Windows] check %JAVA_HOME% for locating Jdk (#74)
* [Windows] check %JAVA_HOME% for locating Jdk Fixes: http://feedback.devdiv.io/606218 Something has happened with Xamarin.Android builds running on Azure DevOps recently, builds are now failing with: ResolveSdks ... Errors C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(721,2): error XA5300: The Java SDK Directory could not be found. Please set via /p:JavaSdkDirectory. [d:\a\1\s\Xamarin.Android.Lite\Xamarin.Android.Lite.csproj] Azure DevOps has posted a "workaround" document: https://github.com/microsoft/azure-pipelines-image-generation/blob/1371aa8548aa135c3be783bd854681118ca10f78/images/win/Vs2019-Server2019-Readme.md#known-issues It suggests adding this property to MSBuild calls: /p:JavaSdkDirectory="$(JAVA_HOME_8_X64)" Reviewing a user's build log from ReactiveUI: https://dev.azure.com/dotnet/ReactiveUI/_build/results?buildId=18505 /p:JavaSdkDirectory=C:/Program%20Files/Java/zulu-8-azure-jdk_8.38.0.13-8.0.212-win_x64 So I tried this with my own repo that has Azure DevOps configured, sure enough a build from June 18, 2019 worked. A rebuild on July 1, 2019 failed with the reported error. * Worked: https://jopepper.visualstudio.com/Jon%20Peppers%20OSS/_build/results?buildId=208 * Failed: https://jopepper.visualstudio.com/Jon%20Peppers%20OSS/_build/results?buildId=209 I can read from the build logs that both `JAVA_HOME` and `JAVA_HOME_8_X64` are set to: C:/Program Files/Java/zulu-8-azure-jdk_8.38.0.13-8.0.212-win_x64 I think this means two things: * Microsoft Open JDK is no longer installed on the `Hosted Windows 2019 with VS2019` pool. * Instead, *yet another JDK* called the Azul Zulu JDK is present... https://docs.microsoft.com/en-us/java/azure/jdk/java-jdk-install?view=azure-java-stable I think we should add a "last resort" lookup for a valid JDK within `JAVA_HOME` on Windows. It does not currently do that. Reviewing the code, I am somewhat confused by `JdkInfo`. Its logic is not run on Windows, and instead we have Windows-specific JDK lookups in `AndroidSdkWindows`. To make things work properly we can just add a last chance lookup for `JAVA_HOME` in `AndroidSdkWindows`. I added a new test for verifying things locally, however... I can't actually run this test on CI, since our current CI machines have the Microsoft Open JDK installed.
1 parent cb41333 commit 9b03310

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkWindows.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,19 @@ IEnumerable<JdkInfo> ToJdkInfos (IEnumerable<string> paths, string locator)
135135
return ToJdkInfos (GetPreferredJdkPaths (), "Preferred Registry")
136136
.Concat (ToJdkInfos (GetOpenJdkPaths (), "OpenJDK"))
137137
.Concat (ToJdkInfos (GetKnownOpenJdkPaths (), "Well-known OpenJDK paths"))
138-
.Concat (ToJdkInfos (GetOracleJdkPaths (), "Oracle JDK"));
138+
.Concat (ToJdkInfos (GetOracleJdkPaths (), "Oracle JDK"))
139+
.Concat (ToJdkInfos (GetEnvironmentJdkPaths (), "Environment Variables"));
140+
}
141+
142+
private static IEnumerable<string> GetEnvironmentJdkPaths ()
143+
{
144+
var environment = new [] { "JAVA_HOME" };
145+
foreach (var key in environment) {
146+
var value = Environment.GetEnvironmentVariable (key);
147+
if (!string.IsNullOrEmpty (value)) {
148+
yield return value;
149+
}
150+
}
139151
}
140152

141153
private static IEnumerable<string> GetPreferredJdkPaths ()

src/Xamarin.Android.Tools.AndroidSdk/Tests/AndroidSdkInfoTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,35 @@ public void Constructor_SetValuesFromPath ()
135135
}
136136
}
137137

138+
[Test]
139+
[Ignore ("This test will only work locally if you rename/remove your Open JDK directory.")]
140+
public void JdkDirectory_JavaHome ()
141+
{
142+
CreateSdks (out string root, out string jdk, out string ndk, out string sdk);
143+
JdkInfoTests.CreateFauxJdk (jdk, releaseVersion: "1.8.999", releaseBuildNumber: "9", javaVersion: "1.8.999-9");
144+
145+
var logs = new StringWriter ();
146+
Action<TraceLevel, string> logger = (level, message) => {
147+
logs.WriteLine ($"[{level}] {message}");
148+
};
149+
150+
string java_home = null;
151+
try {
152+
// We only set via JAVA_HOME
153+
java_home = Environment.GetEnvironmentVariable ("JAVA_HOME", EnvironmentVariableTarget.Process);
154+
Environment.SetEnvironmentVariable ("JAVA_HOME", jdk);
155+
var info = new AndroidSdkInfo (logger, androidSdkPath: sdk, androidNdkPath: ndk, javaSdkPath: "");
156+
157+
Assert.AreEqual (ndk, info.AndroidNdkPath, "AndroidNdkPath not preserved!");
158+
Assert.AreEqual (sdk, info.AndroidSdkPath, "AndroidSdkPath not preserved!");
159+
Assert.AreEqual (jdk, info.JavaSdkPath, "JavaSdkPath not preserved!");
160+
} finally {
161+
if (java_home != null)
162+
Environment.SetEnvironmentVariable ("JAVA_HOME", java_home, EnvironmentVariableTarget.Process);
163+
Directory.Delete (root, recursive: true);
164+
}
165+
}
166+
138167
static bool IsWindows => OS.IsWindows;
139168

140169
static void CreateSdks (out string root, out string jdk, out string ndk, out string sdk)

0 commit comments

Comments
 (0)