JVMInfo* JVMChooser::getJvm(const tstring& javaHomePath, const tstring& binJvmDir) { JVMInfo* pJvmInfo = 0; try { tstring pathToJvm = javaHomePath + tstring(_T("\\bin\\")) + binJvmDir + tstring(_T("\\jvm.dll")); if( LocalUtilities::fileExists(pathToJvm) ) { pJvmInfo = new JVMInfo(); pJvmInfo->setJvmPath(pathToJvm); pJvmInfo->setJavaHomePath(javaHomePath); return pJvmInfo; } pathToJvm = javaHomePath + tstring(_T("\\jre\\bin\\")) + binJvmDir + tstring(_T("\\jvm.dll")); if( LocalUtilities::fileExists(pathToJvm) ) { pJvmInfo = new JVMInfo(); pJvmInfo->setJvmPath(pathToJvm); pJvmInfo->setJavaHomePath(javaHomePath + tstring(_T("\\jre"))); return pJvmInfo; } } catch(...) { DEBUG_SHOW( _T("Exception in JVMChooser.getJvm()") ); ErrHandler::severeError( _T("Error while getting the JVM from the Java home path and JVM type.") ); } return 0; }
JVMInfo* JVMChooser::getJvmFromCustomJvmPath() { JVMInfo* pJvmInfo = 0; try { if( !m_pProperties->getCustomJvmPath().empty() ) { if( LocalUtilities::fileExists(m_pProperties->getCustomJvmPath()) ) { pJvmInfo = new JVMInfo(); pJvmInfo->setJvmPath(m_pProperties->getCustomJvmPath()); return pJvmInfo; } else { throw tstring( _T("This JVM file could not be found: ") + m_pProperties->getCustomJvmPath() ); } } } catch(tstring& se) { DEBUG_SHOW( _T("Exception in JVMChooser.getJvmFromCustomJvmPath(): ") + se ); ErrHandler::severeError( se ); } catch(...) { DEBUG_SHOW( _T("Exception in JVMChooser.getJvmFromCustomJvmPath()") ); ErrHandler::severeError( _T("Error while getting the JVM from the custom jvm path setting.") ); } return 0; }
bool isFirstJvmBetter(JVMInfo& firstJvmInfo, JVMInfo& secondJvmInfo) { if( (firstJvmInfo.getComparableVersion()).compare( (secondJvmInfo.getComparableVersion()) ) < 0 ) { return true; } return false; }
void JVMChooser::breakoutBinJvmDirs(vector<JVMInfo>* pVecJvmInfo) { try { vector<JVMInfo>* pAdditionsVecJvmInfo = new vector<JVMInfo>; // loop through all the JVMs, if there is a server JVM add to additions size_t top = pVecJvmInfo->size(); for( size_t j = 0; j < top; j++ ) { size_t i = top - j - 1; DEBUG_SHOW( _T("Top of first loop through JVMInfos") ); JVMInfo& jvmInfo = pVecJvmInfo->at(i); if( jvmInfo.existsJvmDLL(Properties::CLIENT_BIN_JVM_DIR) && jvmInfo.existsJvmDLL(Properties::SERVER_BIN_JVM_DIR) ) { JVMInfo* pNewJvmInfo = jvmInfo.partialClone(); pNewJvmInfo->setBinJvmDir(Properties::SERVER_BIN_JVM_DIR); pNewJvmInfo->setJvmPath(pNewJvmInfo->getJvmDLLPath(Properties::SERVER_BIN_JVM_DIR)); pAdditionsVecJvmInfo->push_back( *pNewJvmInfo ); jvmInfo.setBinJvmDir(Properties::CLIENT_BIN_JVM_DIR); jvmInfo.setJvmPath(jvmInfo.getJvmDLLPath(Properties::CLIENT_BIN_JVM_DIR)); } else if( jvmInfo.existsJvmDLL(Properties::CLIENT_BIN_JVM_DIR) ) { jvmInfo.setBinJvmDir(Properties::CLIENT_BIN_JVM_DIR); jvmInfo.setJvmPath(jvmInfo.getJvmDLLPath(Properties::CLIENT_BIN_JVM_DIR)); } else if( jvmInfo.existsJvmDLL(Properties::SERVER_BIN_JVM_DIR) ) { jvmInfo.setBinJvmDir(Properties::SERVER_BIN_JVM_DIR); jvmInfo.setJvmPath(jvmInfo.getJvmDLLPath(Properties::SERVER_BIN_JVM_DIR)); } else { pVecJvmInfo->erase(pVecJvmInfo->begin() + i); } } // add the additions which are the server JVMs for( unsigned int i=0; i < pAdditionsVecJvmInfo->size(); i++ ) { JVMInfo& jvmInfo = pAdditionsVecJvmInfo->at(i); pVecJvmInfo->push_back( jvmInfo ); } } catch(...) { DEBUG_SHOW( _T("Exception in JVMChooser.breakoutBinJvmDirs()") ); ErrHandler::severeError( _T("Error while separating out the different JVMs (client or server).") ); } }
void JVMLauncher::launch() { try { // change to the desired diretory tstring workingDir = m_pProperties->getWorkingDir(); if (!workingDir.empty() && _tchdir(workingDir.c_str()) != 0) { throw tstring(_T("Could not change directory to ") + workingDir); } JVMInfo *pBestJvmInfo = m_pProperties->getBestJvmInfo(); if( m_pProperties->getDebugFile().size() > 0 ) { Debug::displayMessage(m_pProperties->getDebugFile(), tstring(_T("The chosen JVM: ")) + pBestJvmInfo->toString()); Debug::displayMessage(m_pProperties->getDebugFile(), tstring(_T("The properties chosen: ")) + m_pProperties->toString()); } DEBUG_SHOW( tstring(_T("pBestJvmInfo->toString()=")) + pBestJvmInfo->toString() ); JNIEnv* pJniEnvironment; JavaVM* pJvm; jint result; jclass javaClass; jmethodID javaMethodId; jobjectArray argsJObjArray; DEBUG_SHOW( tstring(_T("m_pProperties->toString()=")) + m_pProperties->toString() ); #ifdef _UNICODE USES_CONVERSION; #endif // If the check for memory limits flag is set, a dummy window is created // to trigger loading of windowing DLLs. // The dummy window is closed right before the java main method gets called. // Closing it here prevents starting of the splash screen. HWND dummyWnd = NULL; if (m_pProperties->isMemoryCheckLimits()) { dummyWnd = CreateWindowEx(WS_EX_TOOLWINDOW, _T("EDIT"), _T("JanelDummy"), WS_DISABLED| WS_POPUP | WS_VISIBLE, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); } // TODO: pre-loading the CRT shoud be a little bit more intelligent. We should iterate over all existing // msvcr*.dll files and load the one with the highest number.... Well... there should be only one // present because it makes no sense to use/ship different versions of the CRT.... // Trying to pre-load the CRT from the desired JAVA-Directory... tstring crtpath = m_pProperties->getBestJvmInfo()->getJavaHomePath() + tstring(_T("\\bin\\msvcr71.dll")); DEBUG_SHOW(tstring(_T("Trying to load msvcr71.dll (for Java 1.6)..."))); HMODULE crt = LoadLibrary(crtpath.c_str()); if (crt) { DEBUG_SHOW(tstring(_T("msvcr71.dll loaded"))); } else { crtpath = m_pProperties->getBestJvmInfo()->getJavaHomePath() + tstring(_T("\\bin\\msvcr100.dll")); DEBUG_SHOW(tstring(_T("Trying to load msvcr100.dll (for Java 1.7)..."))); crt = LoadLibrary(crtpath.c_str()); if(crt) { DEBUG_SHOW(tstring(_T("msvcr100.dll loaded"))); } } // Show the splash screen tstring splash = m_pProperties->getSplash(); if (!splash.empty()) { DEBUG_SHOW(tstring(_T("Showing splash screen ")) + splash); tstring sspath = m_pProperties->getBestJvmInfo()->getJavaHomePath() + tstring(_T("\\bin\\splashscreen.dll")); DEBUG_SHOW(tstring(_T("Loading splashscreen.dll from ")) + sspath); HMODULE hSplashLibrary = LoadLibrary(sspath.c_str()); if (hSplashLibrary) { SplashInit_t splashInit = (SplashInit_t)GetProcAddress(hSplashLibrary, "SplashInit"); splashInit(); SplashLoadFile_t splashLoadFile = (SplashLoadFile_t)GetProcAddress(hSplashLibrary, "SplashLoadFile"); splashLoadFile(W2A(splash.c_str())); SplashSetFileJarName_t splashSetFileJarName = (SplashSetFileJarName_t)GetProcAddress(hSplashLibrary, "SplashSetFileJarName"); splashSetFileJarName(W2A(splash.c_str()), NULL); } else DEBUG_SHOW(tstring(_T("Failed to load splashscreen.dll"))); } // create JVM HINSTANCE hJvm = NULL; const TCHAR* pJvmPath = pBestJvmInfo->getJvmPath().c_str(); DEBUG_SHOW( tstring(_T("pJvmPath()=")) + tstring(pJvmPath) ); hJvm = LoadLibrary(pJvmPath); typedef jint (JNICALL CreateJavaVM_t)( JavaVM**, void**, void* ); CreateJavaVM_t* CreateJavaVM; CreateJavaVM = (CreateJavaVM_t*)GetProcAddress( hJvm, "JNI_CreateJavaVM" ); DEBUG_SHOW(_T("Just about to CreateJavaVM")); // Evaluation of memory settings considers the current state of the stack. // It finds the largest free memory region and limits the size of the object // heap to this size plus some overhead for the VM itsself. In cases when // the process loads additional DLLs prior to starting the VM, e.g. on machines with // IME (Input Method Editor - japanese...) this leads to a not enough heap space error. // Therefore we need to evaluate memory settings as late as possible. m_pProperties->evaluateMemorySettings(); // setup options JavaVMInitArgs jvmInitArgs; setupJavaVMInitArgs(jvmInitArgs); result = CreateJavaVM(&pJvm,(void**)&pJniEnvironment,&jvmInitArgs); teardownJavaVMInitArgs(jvmInitArgs); if (result < 0) { throw tstring(_T("Cannot create Java VM.")); } if(pJniEnvironment->ExceptionOccurred() != 0) { pJniEnvironment->ExceptionDescribe(); throw tstring(_T("Error occurred while creating Java VM.")); } m_pVM = pJvm; // find main class tstring& mainClass = m_pProperties->getMainClass(); #ifdef _UNICODE ::std::string utf8MainClass = LocalUtilities::convertWideStringToUTF8(mainClass); #else ::std::string utf8MainClass = m_pProperties->getMainClass(); #endif javaClass = pJniEnvironment->FindClass( utf8MainClass.c_str() ); if(pJniEnvironment->ExceptionOccurred() != 0) { pJniEnvironment->ExceptionDescribe(); throw tstring(_T("Error occurred while attempting to find Java class ") + m_pProperties->getMainClass()); } if (javaClass == 0) { throw tstring( _T("Cannot find main Java class ") + (m_pProperties->getMainClass()) ); } javaMethodId = pJniEnvironment->GetStaticMethodID(javaClass, "main", "([Ljava/lang/String;)V"); if(pJniEnvironment->ExceptionOccurred() != 0) { pJniEnvironment->ExceptionDescribe(); throw tstring(_T("Error occurred while getting main method in Java class ") + m_pProperties->getMainClass()); } if (javaMethodId == 0) { throw tstring(_T("Cannot find main method in Java class.")); } // set command-line arguments to pass to main method vector<tstring>& argsVector = m_pProperties->getCommandLineArguments(); size_t vecSize = argsVector.size(); assert(vecSize < ((size_t) std::numeric_limits<jsize>::max())); argsJObjArray = (jobjectArray)pJniEnvironment->NewObjectArray( (jsize) vecSize, pJniEnvironment->FindClass("java/lang/String"), pJniEnvironment->NewStringUTF("")); if (argsJObjArray == 0) { throw tstring(_T("Error creating new object array to hold command line arguments.")); } for(unsigned int i=0; i < argsVector.size(); i++) { DEBUG_STMT( TCHAR debugstr[5000]; ); DEBUG_STMT( _stprintf(debugstr, _T("command line arg[%u]=%s"), i, argsVector.at(i).c_str()); ); DEBUG_SHOW( debugstr ); size_t argSize = argsVector.at(i).length(); assert(argSize < ((size_t) std::numeric_limits<jsize>::max())); pJniEnvironment->SetObjectArrayElement(argsJObjArray, i, pJniEnvironment->NewString((const jchar*)argsVector.at(i).c_str(), (jsize) argSize)); }
void WindowsRegistry::addAllJreJvms(vector<JVMInfo>* pVecJvmInfo, const tstring& regKey) { try { LONG result; HKEY hKey; result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regKey.c_str(),0,KEY_READ,&hKey); if (result != ERROR_SUCCESS) { // key may not exist so exit return; } TCHAR lpName[MAX_PATH]; for (DWORD index = 0, result = ERROR_SUCCESS; result == ERROR_SUCCESS; index++) { DWORD lpcName = MAX_PATH; result = RegEnumKeyEx(hKey, index, lpName, &lpcName, NULL, NULL, NULL, NULL); if( result == ERROR_SUCCESS ) { tstring dirName(lpName); if( dirName.empty() ) { continue; } tstring fullKeyPath = regKey + tstring(_T("\\")) + dirName; DEBUG_SHOW( tstring(_T("fullKeyPath=")) + fullKeyPath ); tstring& javaHome = getStringValue(fullKeyPath, _T("JavaHome")); if( javaHome.empty() ) { continue; } JVMInfo *pJvmInfo = new JVMInfo; pJvmInfo->setJavaBundle(Properties::JRE_JAVA_BUNDLE); pJvmInfo->setJavaHomePath(javaHome); pJvmInfo->setVersion(dirName); pVecJvmInfo->push_back(*pJvmInfo); } } RegCloseKey(hKey); } catch(tstring& se) { ErrHandler::severeError( se ); } catch(...) { DEBUG_SHOW( _T("Exception in WindowsRegistry.addAllJreJvms()") ); ErrHandler::severeError( _T("Error getting JVM paths from registry.") ); } }