in src/native/windows/src/javajni.c [194:365]
static BOOL __apxLoadJvmDll(APXHANDLE hPool, LPCWSTR szJvmDllPath, LPCWSTR szJavaHome)
{
UINT errMode;
WCHAR jreAltPath[SIZ_PATHLEN];
LPWSTR dllJvmPath = (LPWSTR)szJvmDllPath;
DYNLOAD_FPTR_DECLARE(SetDllDirectoryW);
DWORD i, l = 0;
WCHAR jreBinPath[SIZ_PATHLEN];
if (!IS_INVALID_HANDLE(_st_sys_jvmDllHandle))
return TRUE; /* jvm.dll is already loaded */
if (dllJvmPath && *dllJvmPath) {
/* Explicit JVM path.
* Check if provided argument is valid
*/
if (GetFileAttributesW(dllJvmPath) == INVALID_FILE_ATTRIBUTES) {
/* DAEMON-247: Invalid RuntimeLib explicitly specified is error.
*/
apxLogWrite(APXLOG_MARK_ERROR "Invalid RuntimeLib specified '%S'", dllJvmPath);
return FALSE;
}
apxLogWrite(APXLOG_MARK_DEBUG "Explicit RuntimeLib specified '%S'", dllJvmPath);
}
else {
// No explicit JVM path. Use the standard registry locations.
dllJvmPath = apxGetJavaSoftRuntimeLib(NULL);
apxLogWrite(APXLOG_MARK_DEBUG "No explicit RuntimeLib specified. Checking registry. Found '%S'", dllJvmPath);
}
if (GetFileAttributesW(dllJvmPath) == INVALID_FILE_ATTRIBUTES) {
/* DAEMON-184: RuntimeLib registry key is invalid.
* Check from Jre JavaHome registry key directly
*/
LPWSTR szJreHome = apxGetJavaSoftHome(NULL, TRUE);
if (szJreHome) {
apxLogWrite(APXLOG_MARK_DEBUG "Invalid RuntimeLib '%S', Checking registry for JRE home. Found '%S'", dllJvmPath, szJreHome);
lstrlcpyW(jreAltPath, SIZ_PATHLEN, szJreHome);
lstrlcatW(jreAltPath, SIZ_PATHLEN, L"\\bin\\server\\jvm.dll");
dllJvmPath = jreAltPath;
} else {
apxLogWrite(APXLOG_MARK_DEBUG "Invalid RuntimeLib '%S', Checking registry for JRE home. None found.", dllJvmPath);
}
}
if (GetFileAttributesW(dllJvmPath) == INVALID_FILE_ATTRIBUTES) {
/* DAEMON-247: JavaSoft JRE registry keys are invalid / not present
* Check from Procrun's JavaHome registry key
*/
if (szJavaHome) {
apxLogWrite(APXLOG_MARK_DEBUG "Using explicitly configured JavaHome '%S'", szJavaHome);
lstrlcpyW(jreAltPath, SIZ_PATHLEN, szJavaHome);
lstrlcatW(jreAltPath, SIZ_PATHLEN, L"\\bin\\server\\jvm.dll");
dllJvmPath = jreAltPath;
}
}
if (GetFileAttributesW(dllJvmPath) == INVALID_FILE_ATTRIBUTES) {
/* DAEMON-404: JRE home in registry invalid / not present.
* Explicit JavaHome invalid / not present
* Check from JDK JavaHome registry key directly
*/
LPWSTR szJdkHome = apxGetJavaSoftHome(NULL, FALSE);
if (szJdkHome) {
apxLogWrite(APXLOG_MARK_DEBUG "Invalid RuntimeLib '%S', Checking registry for JDK home. Found '%S'", dllJvmPath, szJdkHome);
lstrlcpyW(jreAltPath, SIZ_PATHLEN, szJdkHome);
lstrlcatW(jreAltPath, SIZ_PATHLEN, L"\\bin\\server\\jvm.dll");
dllJvmPath = jreAltPath;
} else {
apxLogWrite(APXLOG_MARK_DEBUG "Invalid RuntimeLib '%S', Checking registry for JDK home. None found.", dllJvmPath);
}
}
if (!dllJvmPath) {
apxLogWrite(APXLOG_MARK_ERROR "No JVM configured or found in registry. Unable to start service.");
return FALSE;
}
/* Suppress the not found system popup message */
errMode = SetErrorMode(SEM_FAILCRITICALERRORS);
lstrlcpyW(jreBinPath, SIZ_PATHLEN, dllJvmPath);
for (i = lstrlenW(jreBinPath); i > 0, l < 2; i--) {
if (jreBinPath[i] == L'\\' || jreBinPath[i] == L'/') {
jreBinPath[i] = L'\0';
l++;
}
}
/* Add Java bin path to the PATH to fix loading of awt.dll */
apxLogWrite(APXLOG_MARK_DEBUG "Adding Java bin path to the PATH to fix loading of awt.dll: '%S'", jreBinPath);
apxAddToPathW(hPool, jreBinPath);
/* Set the environment using putenv, so JVM can use it */
apxSetInprocEnvironment();
apxLogWrite(APXLOG_MARK_DEBUG "Loading JVM DLL '%S'", dllJvmPath);
_st_sys_jvmDllHandle = LoadLibraryExW(dllJvmPath, NULL, 0);
if (IS_INVALID_HANDLE(_st_sys_jvmDllHandle) &&
GetFileAttributesW(dllJvmPath) != INVALID_FILE_ATTRIBUTES) {
WCHAR crtBinPath[SIZ_PATHLEN];
/* There is a file but cannot be loaded.
* Try to load the MSVCRTxx.dll before JVM.dll
*/
apxLogWrite(APXLOG_MARK_ERROR "Found '%S' but couldn't load it.", dllJvmPath);
lstrlcpyW(jreBinPath, SIZ_PATHLEN, dllJvmPath);
if(l == 2) {
lstrlcpyW(crtBinPath, SIZ_PATHLEN, jreBinPath);
lstrlcatW(crtBinPath, SIZ_PATHLEN, MSVCRT71_DLLNAME);
if (GetFileAttributesW(crtBinPath) != INVALID_FILE_ATTRIBUTES) {
apxLogWrite(APXLOG_MARK_DEBUG "Loading '%S'.", crtBinPath);
if (LoadLibraryW(crtBinPath)) {
/* Found MSVCRTxx.dll
*/
apxLogWrite(APXLOG_MARK_DEBUG "Preloaded '%S'", crtBinPath);
}
else {
apxLogWrite(APXLOG_MARK_DEBUG "Failed preloading '%S'.", crtBinPath);
}
}
}
}
/* This shouldn't happen, but try to search in %PATH% */
if (IS_INVALID_HANDLE(_st_sys_jvmDllHandle)) {
apxLogWrite(APXLOG_MARK_DEBUG "Invalid JVM DLL handle.");
apxLogWrite(APXLOG_MARK_DEBUG "Loading JVM DLL '%S' using LOAD_WITH_ALTERED_SEARCH_PATH.", dllJvmPath);
_st_sys_jvmDllHandle = LoadLibraryExW(dllJvmPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
if (IS_INVALID_HANDLE(_st_sys_jvmDllHandle)) {
apxLogWrite(APXLOG_MARK_DEBUG "Invalid JVM DLL handle.");
DYNLOAD_FPTR_ADDRESS(SetDllDirectoryW, KERNEL32);
if (l == 2) {
apxLogWrite(APXLOG_MARK_DEBUG "Setting DLL search path to '%S'", jreBinPath);
DYNLOAD_CALL(SetDllDirectoryW)(jreBinPath);
}
apxLogWrite(APXLOG_MARK_DEBUG "Loading JVM DLL '%S'.", dllJvmPath);
_st_sys_jvmDllHandle = LoadLibraryExW(dllJvmPath, NULL, 0);
if (IS_INVALID_HANDLE(_st_sys_jvmDllHandle)) {
apxLogWrite(APXLOG_MARK_DEBUG "Invalid JVM DLL handle.");
apxLogWrite(APXLOG_MARK_DEBUG "Loading JVM DLL '%S' using LOAD_WITH_ALTERED_SEARCH_PATH.", dllJvmPath);
_st_sys_jvmDllHandle = LoadLibraryExW(dllJvmPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
}
}
/* Restore the error mode signalization */
SetErrorMode(errMode);
if (IS_INVALID_HANDLE(_st_sys_jvmDllHandle)) {
apxLogWrite(APXLOG_MARK_ERROR "Invalid JVM DLL handle.");
apxLogWrite(APXLOG_MARK_SYSERR);
return FALSE;
}
DYNLOAD_FPTR_LOAD(JNI_GetDefaultJavaVMInitArgs, _st_sys_jvmDllHandle);
DYNLOAD_FPTR_LOAD(JNI_CreateJavaVM, _st_sys_jvmDllHandle);
DYNLOAD_FPTR_LOAD(JNI_GetCreatedJavaVMs, _st_sys_jvmDllHandle);
DYNLOAD_FPTR_LOAD(JVM_DumpAllStacks, _st_sys_jvmDllHandle);
if (!DYNLOAD_FPTR(JNI_GetDefaultJavaVMInitArgs) ||
!DYNLOAD_FPTR(JNI_CreateJavaVM) ||
!DYNLOAD_FPTR(JNI_GetCreatedJavaVMs)) {
apxLogWrite(APXLOG_MARK_SYSERR);
apxLogWrite(APXLOG_MARK_DEBUG "Freeing JVM DLL.");
FreeLibrary(_st_sys_jvmDllHandle);
_st_sys_jvmDllHandle = NULL;
apxLogWrite(APXLOG_MARK_ERROR "Failed loading JNI function pointers.");
return FALSE;
}
/* Real voodoo ... */
return TRUE;
}