JDK-8248987 : AOT's Linker.java seems to eagerly fail-fast on Windows.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11,14,15,16
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • CPU: generic
  • Submitted: 2020-07-07
  • Updated: 2021-02-03
  • Resolved: 2020-07-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 13 JDK 15 JDK 16
11.0.10-oracleFixed 13.0.6Fixed 15.0.1Fixed 16 b06Fixed
Related Reports
Relates :  
Description
jtreg by design curates the environment variables exposed to the test subject and if devkit is not used all of AOT regression tests will fail.

I encountered this on JDK11.08, but this issue exists in the latest release.

The reason is as follows:
1. Consider this:
https://hg.openjdk.java.net/jdk-updates/jdk11u/file/030bc020dc04/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java#l203

The logic tries to get the environment variable as follows:

String programFilesX86 = System.getenv("ProgramFiles(x86)���);
And Linker.java will keel over if ���ProgramFiles(x86)���   is not present.

2. The next failure is here:
https://hg.openjdk.java.net/jdk-updates/jdk11u/file/030bc020dc04/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java#l226
vswhere.exe will return an empty output when the environment variable ���ProgramData��� is not defined, essentially vswhere.exe fails silently.

The above logic seems to fail-fast, if the environment variable ���programFilesX86��� does not exist, and even if it did and not having ProgramData will cause vswhere.exe will fail silently  in which case Linker.java will never find older versions of VisualStudio as enumerated by VSVERSIONS. 

Comments
Fix request (13u) Requesting backport to 13u for parity with 11u. The patch applies cleanly. Changes are jaotc tool specific, tested with aot tests.
19-01-2021

jdk11 backport request I would like to have the patch in openjdk11 as well, for better parity with 11.0.9-oracle. The patch applies cleanly.
05-08-2020

Fix Request for JDK 15 update. It is important fix to avoid a lot of tests failure on Windows systems when AOT compilation is used. Note, we uses AOT compilation for JCK testing for example. Changes are JAOTC tool specific and small. They don't affect Java application execution. Tested in Mach5 running AOT tests. Webrev: https://cr.openjdk.java.net/~kvn/8248987/webrev.00/ Review: https://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2020-July/038914.html
28-07-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/8d1e1baf9600 User: kvn Date: 2020-07-08 22:46:15 +0000
08-07-2020

As you see, this fix will print exception message from getVC141AndNewerLinker() with --verbose flag and additionally call stack with --debug. I included this because it is simple code change.
08-07-2020

I updated webrev.00 with orElseThrow() as you suggested. Fix can be pushed upstream into graal repo at the same time.
08-07-2020

[~kvn], you don't actually need to change `orElseThrow to orElse(null) in String installationPath = getLines(...`, you can just change `InternalError` to `IllegalStateException` in the excpetion supplier.
08-07-2020

looks good to me. btw, isn't upstream of jaotc in graal repo now? so the fix will have to go there.
08-07-2020

Good suggestion. How about this: https://cr.openjdk.java.net/~kvn/8248987/webrev.00/
08-07-2020

> Should we also replace exceptions with NULL return in the rest of method? thought about it a bit more, if we are to treat all problems in getVC141AndNewerLinker() as non-fatal, we can simply change InternalError to an exception, e.g. IllegalStateException, which will be caught and printed out in getWindowsLinkPath. this will also provide some information to the end-user (admittedly, not in the best possible form)
08-07-2020

> The last character of jaotc implies its a compiler, and all compilers will emit warnings and errors, although one can emit warnings under a verbose flag and suppress otherwise. I'm not saying that jaotc shouldn't emit warnings, I'm just saying that it currently does not. and changing this as part of a bug fix doesn't seem right to me. Instead, I'm suggesting opening an umbrella RFE to improve the diagnosticity of jaotc tool as I'm sure there are other places that silently ignore problems.
08-07-2020

> Should we also replace exceptions with NULL return in the rest of method? from what I see, all other InternalError-s in getVC141AndNewerLinker() happen only if something is wrong w/ the env, so I'm not sure if it's a good idea to continue in such case; on the other hand, one can have broken `vswhere.exe`, but working VS2015, so it might make sense to search for older VS in such case.
08-07-2020

The last character of jaotc implies its a compiler, and all compilers will emit warnings and errors, although one can emit warnings under a verbose flag and suppress otherwise.
08-07-2020

Should we also replace exceptions with NULL return in the rest of method? We can print diagnostic information when --debug flag is used with jaotc (or even --verbose).
08-07-2020

Although I'm highly sympathetic to having more diagnostic information provided to end-users, I don't think it's appropriate here (at least not as part of this bug fix), b/c j.t.jaotc.Linker doesn't print any other information when it tries to find a linker.
08-07-2020

The suggested fix will work, but I think it would be good to output some warnings on stderr.
08-07-2020

suggested fix: in the cases described by [~ksrini] return null instead of throwing IE: diff -r 664eff33990a src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java --- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java Tue Jun 30 19:20:22 2020 +0200 +++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Linker.java Tue Jul 07 22:04:56 2020 -0700 @@ -193,7 +193,8 @@ private static Path getVC141AndNewerLinker() throws Exception { String programFilesX86 = System.getenv("ProgramFiles(x86)"); if (programFilesX86 == null) { - throw new InternalError("Could not read the ProgramFiles(x86) environment variable"); + // we might still be able to find older VS + return null; } Path vswhere = Paths.get(programFilesX86 + "\\Microsoft Visual Studio\\Installer\\vswhere.exe"); if (!Files.exists(vswhere)) { @@ -213,8 +214,11 @@ } throw new InternalError(errorMessage); } - - String installationPath = getLines(process.getInputStream()).findFirst().orElseThrow(() -> new InternalError("Unexpected empty output from vswhere")); + String installationPath = getLines(process.getInputStream()).findFirst().orElse(null); + if (installationPath == null) { + // we might still be able to find older VS + return null; + } Path vcToolsVersionFilePath = Paths.get(installationPath, "VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt"); List<String> vcToolsVersionFileLines = Files.readAllLines(vcToolsVersionFilePath); if (vcToolsVersionFileLines.isEmpty()) {
08-07-2020