JDK-8202559 : Tests which start VM using JNI start failing after compile upgrade to VC 2017
  • Type: Bug
  • Component: hotspot
  • Sub-Component: test
  • Affected Version: 11
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-05-02
  • Updated: 2018-06-26
  • Resolved: 2018-06-19
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
11 b19Fixed
Related Reports
Relates :  
Relates :  
Description
Tests 
nsk/coverage/jni/jni0XX 
and
fromTonga/runtime/jni/WindowsExceptionFilter/WindowsExceptionFilter02/TestDescription.java  

fails in windows after compiler upgrade to VC2017.

These tests starts java from native executable using JNI. They fail to find vcruntime140.dll. 

Test is reproduced on both Oracle and Open JDK. Test pass if this library could be found in PATH.
Comments
http://cr.openjdk.java.net/~iignatyev//8202559/webrev.00/index.html
18-06-2018

FWIW this looks similar to JDK-8195002
18-06-2018

Attaching suggested patch for ExecDriver.
18-06-2018

Removing regression label since this is not a regression. It was only less likely to happen before, but the underlying mechanisms are exactly the same.
18-06-2018

Moving to hotspot/test as the problem is not in the build but in the setup of the tests.
18-06-2018

Another possibility would be to explicitly load them via System.loadLibrary at startup (which is what we did for JavaFX), but that might have an undesirable impact on startup performance.
12-06-2018

The root of the problem here is that we have jvm.dll in a subdirectory of bin, so it's not in the same directory as the other dlls. On other platforms, we solve this by adding an rpath $ORIGIN/.. to libjvm.so, but sadly, Windows has no such construct. The standard workaround, which has been necessary for a long time, has been to explicitly preload the msvcr*.dll files before loading jvm.dll. When upgrading the compiler, there are two potential problems with VS2017: * An older system, like Windows 7 or 8, may not have the latest msvcr/vcruntime*.dll files installed on the system. They probably had the older msvcr120.dll from VS2013, which is why this worked without preloading. * With VS2017, the UCRT was introduced, which are all the dlls listed above by Kevin. We bundle these dlls with the jdk so that Java will be runnable on old non updated Windows systems, but Microsoft prefers that they are installed on the OS through Windows updates. So, on a properly updated Windows system, this shouldn't be a problem. You may need to explicitly install the latest VS runtime dlls to achieve this however. If we need to support non updated Window systems, then a workaround is needed. One possibility is to simply copy all the MS dlls into the server subdir (and now also the hardened subdir). I would hate to have to do that. Another possible workaround in a test is to add the jdk/bin directory to the dll search path using AddDllDirectory before loading jvm.dll from native. (https://msdn.microsoft.com/en-us/library/windows/desktop/hh310513%28v=vs.85%29.aspx) This is possible since XPSP1 so should be safe to use for us. The problematic need for preloading is a long standing known issue and we have at least one externally filed bug about this which we have so far refused to do anything about, simply because there is no easy solution.
12-06-2018

Is this still a problem?
12-06-2018

If you can come up with a solution that doesn't require explicit loading of the libraries, that would be better, of course.
03-05-2018

I agree with [~dholmes]. The code above looks like a workaround, not a proper solution.
03-05-2018

I think it important to understand what has changed here rather than just working around it in Java code. It should not be necessary to explicitly load system libraries like this, It should be handled by appropriate build directives that create the necessary runtime linkages. If VS2017 has changed something here then we need to know what it is.
02-05-2018

For FX, we load them explicitly using System.loadLibrary in the following order, although the order of the api-ms-win* doesn't seem to matter. What does matter is that all of the api-ms-* DLLs are loaded before ucrtbase.dll which is loaded before the VS2017 DLLs: private static final String[] msLibNames = { "api-ms-win-core-console-l1-1-0", "api-ms-win-core-datetime-l1-1-0", "api-ms-win-core-debug-l1-1-0", "api-ms-win-core-errorhandling-l1-1-0", "api-ms-win-core-file-l1-1-0", "api-ms-win-core-file-l1-2-0", "api-ms-win-core-file-l2-1-0", "api-ms-win-core-handle-l1-1-0", "api-ms-win-core-heap-l1-1-0", "api-ms-win-core-interlocked-l1-1-0", "api-ms-win-core-libraryloader-l1-1-0", "api-ms-win-core-localization-l1-2-0", "api-ms-win-core-memory-l1-1-0", "api-ms-win-core-namedpipe-l1-1-0", "api-ms-win-core-processenvironment-l1-1-0", "api-ms-win-core-processthreads-l1-1-0", "api-ms-win-core-processthreads-l1-1-1", "api-ms-win-core-profile-l1-1-0", "api-ms-win-core-rtlsupport-l1-1-0", "api-ms-win-core-string-l1-1-0", "api-ms-win-core-synch-l1-1-0", "api-ms-win-core-synch-l1-2-0", "api-ms-win-core-sysinfo-l1-1-0", "api-ms-win-core-timezone-l1-1-0", "api-ms-win-core-util-l1-1-0", "api-ms-win-crt-conio-l1-1-0", "api-ms-win-crt-convert-l1-1-0", "api-ms-win-crt-environment-l1-1-0", "api-ms-win-crt-filesystem-l1-1-0", "api-ms-win-crt-heap-l1-1-0", "api-ms-win-crt-locale-l1-1-0", "api-ms-win-crt-math-l1-1-0", "api-ms-win-crt-multibyte-l1-1-0", "api-ms-win-crt-private-l1-1-0", "api-ms-win-crt-process-l1-1-0", "api-ms-win-crt-runtime-l1-1-0", "api-ms-win-crt-stdio-l1-1-0", "api-ms-win-crt-string-l1-1-0", "api-ms-win-crt-time-l1-1-0", "api-ms-win-crt-utility-l1-1-0", "ucrtbase", // Finally load VS 2017 DLLs in the following order "vcruntime140", "msvcp140", "concrt140" }; Then we (effectively) do this: for (String libName : msLibNames) { try { System.loadLibrary(libName); } catch (Throwable t) { if (verbose) { System.err.println("Error: failed to load " + libName + ".dll : " + t); } } }
02-05-2018

Btw, we ran into this issue with FX when we upgraded to VS2017. See: JDK-8187043.
02-05-2018

A better fix might be to load the libraries explicitly, which is also part of the fix needed for JDK-8202557. We did this for FX when upgrading to VS 2017.
02-05-2018

I think that test failure could be fixed by adding <jdk-root>/bin into native path. However it is unclear if it is a correct way to fix this bug. And if it is a correct to request vcruntime140.dll to be added in the path then should be any documentation updated for this?
02-05-2018