8244634: LoadLibraryW failed from tools/jpackage tests after JDK-8242302
Reviewed-by: herrick, almatvee
This commit is contained in:
parent
dc54da232d
commit
e48410a466
@ -46,6 +46,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tstring getPath() const {
|
||||||
|
return jvmPath;
|
||||||
|
}
|
||||||
|
|
||||||
void launch();
|
void launch();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -28,10 +28,14 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "AppLauncher.h"
|
#include "AppLauncher.h"
|
||||||
|
#include "JvmLauncher.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Dll.h"
|
||||||
|
#include "Toolbox.h"
|
||||||
#include "FileUtils.h"
|
#include "FileUtils.h"
|
||||||
#include "UniqueHandle.h"
|
#include "UniqueHandle.h"
|
||||||
#include "ErrorHandling.h"
|
#include "ErrorHandling.h"
|
||||||
|
#include "WinSysInfo.h"
|
||||||
#include "WinErrorHandling.h"
|
#include "WinErrorHandling.h"
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +45,61 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
std::unique_ptr<Dll> loadDllWithAlteredPATH(const tstring& dllFullPath) {
|
||||||
|
LOG_TRACE_FUNCTION();
|
||||||
|
|
||||||
|
const tstring vanillaPathEnvVariable = SysInfo::getEnvVariable(_T("PATH"));
|
||||||
|
|
||||||
|
tstring pathEnvVariable = vanillaPathEnvVariable
|
||||||
|
+ _T(";")
|
||||||
|
+ FileUtils::dirname(dllFullPath);
|
||||||
|
|
||||||
|
SysInfo::setEnvVariable(_T("PATH"), pathEnvVariable);
|
||||||
|
|
||||||
|
LOG_TRACE(tstrings::any() << "New value of PATH: " << pathEnvVariable);
|
||||||
|
|
||||||
|
// Schedule restore of PATH after attempt to load the given dll
|
||||||
|
const auto resetPATH = runAtEndOfScope([&vanillaPathEnvVariable]() -> void {
|
||||||
|
SysInfo::setEnvVariable(_T("PATH"), vanillaPathEnvVariable);
|
||||||
|
});
|
||||||
|
|
||||||
|
return std::unique_ptr<Dll>(new Dll(dllFullPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Dll> loadDllWithAddDllDirectory(const tstring& dllFullPath) {
|
||||||
|
LOG_TRACE_FUNCTION();
|
||||||
|
|
||||||
|
const tstring dirPath = FileUtils::dirname(dllFullPath);
|
||||||
|
|
||||||
|
typedef DLL_DIRECTORY_COOKIE(WINAPI *AddDllDirectoryFunc)(PCWSTR);
|
||||||
|
|
||||||
|
DllFunction<AddDllDirectoryFunc> _AddDllDirectory(
|
||||||
|
Dll("kernel32.dll", Dll::System()), "AddDllDirectory");
|
||||||
|
|
||||||
|
AddDllDirectoryFunc func = _AddDllDirectory;
|
||||||
|
DLL_DIRECTORY_COOKIE res = func(dirPath.c_str());
|
||||||
|
if (!res) {
|
||||||
|
JP_THROW(SysError(tstrings::any()
|
||||||
|
<< "AddDllDirectory(" << dirPath << ") failed", func));
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_TRACE(tstrings::any() << "AddDllDirectory(" << dirPath << "): OK");
|
||||||
|
|
||||||
|
// Important: use LOAD_LIBRARY_SEARCH_DEFAULT_DIRS flag,
|
||||||
|
// but not LOAD_LIBRARY_SEARCH_USER_DIRS!
|
||||||
|
HMODULE dllHandle = LoadLibraryEx(dllFullPath.c_str(), NULL,
|
||||||
|
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||||
|
|
||||||
|
LOG_TRACE(tstrings::any() << "LoadLibraryEx(" << dllFullPath
|
||||||
|
<< ", LOAD_LIBRARY_SEARCH_DEFAULT_DIRS): " << dllHandle);
|
||||||
|
|
||||||
|
const auto freeDll = runAtEndOfScope([&dllHandle]() -> void {
|
||||||
|
Dll::freeLibrary(dllHandle);
|
||||||
|
});
|
||||||
|
|
||||||
|
return std::unique_ptr<Dll>(new Dll(dllFullPath));
|
||||||
|
}
|
||||||
|
|
||||||
void launchApp() {
|
void launchApp() {
|
||||||
// [RT-31061] otherwise UI can be left in back of other windows.
|
// [RT-31061] otherwise UI can be left in back of other windows.
|
||||||
::AllowSetForegroundWindow(ASFW_ANY);
|
::AllowSetForegroundWindow(ASFW_ANY);
|
||||||
@ -48,13 +107,31 @@ void launchApp() {
|
|||||||
const tstring launcherPath = SysInfo::getProcessModulePath();
|
const tstring launcherPath = SysInfo::getProcessModulePath();
|
||||||
const tstring appImageRoot = FileUtils::dirname(launcherPath);
|
const tstring appImageRoot = FileUtils::dirname(launcherPath);
|
||||||
|
|
||||||
AppLauncher()
|
std::unique_ptr<Jvm> jvm(AppLauncher()
|
||||||
.setImageRoot(appImageRoot)
|
.setImageRoot(appImageRoot)
|
||||||
.addJvmLibName(_T("bin\\jli.dll"))
|
.addJvmLibName(_T("bin\\jli.dll"))
|
||||||
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("app"))
|
.setAppDir(FileUtils::mkpath() << appImageRoot << _T("app"))
|
||||||
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
.setDefaultRuntimePath(FileUtils::mkpath() << appImageRoot
|
||||||
<< _T("runtime"))
|
<< _T("runtime"))
|
||||||
.launch();
|
.createJvmLauncher());
|
||||||
|
|
||||||
|
std::unique_ptr<Dll> jvmDll;
|
||||||
|
try {
|
||||||
|
// Try load JVM DLL.
|
||||||
|
jvmDll = std::unique_ptr<Dll>(new Dll(jvm->getPath()));
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
// JVM DLL load failed, though it exists in file system.
|
||||||
|
try {
|
||||||
|
// Try adjust the DLL search paths with AddDllDirectory() WINAPI CALL
|
||||||
|
jvmDll = loadDllWithAddDllDirectory(jvm->getPath());
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
// AddDllDirectory() didn't work. Try altering PATH environment
|
||||||
|
// variable as the last resort.
|
||||||
|
jvmDll = loadDllWithAlteredPATH(jvm->getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jvm->launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -114,6 +114,16 @@ HMODULE getCurrentModuleHandle()
|
|||||||
return hmodule;
|
return hmodule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setEnvVariable(const tstring& name, const tstring& value)
|
||||||
|
{
|
||||||
|
if (!SetEnvironmentVariable(name.c_str(), value.c_str())) {
|
||||||
|
JP_THROW(SysError(tstrings::any()
|
||||||
|
<< "SetEnvironmentVariable("
|
||||||
|
<< name << ", " << value
|
||||||
|
<< ") failed", SetEnvironmentVariable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tstring getCurrentModulePath()
|
tstring getCurrentModulePath()
|
||||||
{
|
{
|
||||||
return getModulePath(getCurrentModuleHandle());
|
return getModulePath(getCurrentModuleHandle());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -43,6 +43,8 @@ namespace SysInfo {
|
|||||||
// Returns handle of the current module (exe or dll).
|
// Returns handle of the current module (exe or dll).
|
||||||
// The function assumes this code is statically linked to the module.
|
// The function assumes this code is statically linked to the module.
|
||||||
HMODULE getCurrentModuleHandle();
|
HMODULE getCurrentModuleHandle();
|
||||||
|
|
||||||
|
void setEnvVariable(const tstring& name, const tstring& value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user