| /* |
| * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| #include <algorithm> |
| #include "AppLauncher.h" |
| #include "JvmLauncher.h" |
| #include "CfgFile.h" |
| #include "Log.h" |
| #include "Dll.h" |
| #include "Toolbox.h" |
| #include "SysInfo.h" |
| #include "FileUtils.h" |
| |
| |
| AppLauncher::AppLauncher() { |
| setInitJvmFromCmdlineOnly(false); |
| launcherPath = SysInfo::getProcessModulePath(); |
| args = SysInfo::getCommandArgs(); |
| } |
| |
| |
| namespace { |
| |
| struct find_jvmlib { |
| find_jvmlib(const tstring& v): runtimePath(v) { |
| } |
| |
| bool operator () (const tstring& jvmLibName) const { |
| const tstring path = FileUtils::mkpath() << runtimePath << jvmLibName; |
| return FileUtils::isFileExists(path); |
| } |
| |
| private: |
| const tstring& runtimePath; |
| }; |
| |
| tstring findJvmLib(const CfgFile& cfgFile, const tstring& defaultRuntimePath, |
| const tstring_array& jvmLibNames) { |
| const CfgFile::Properties& appOptions = cfgFile.getProperties( |
| SectionName::Application); |
| |
| const CfgFile::Properties::const_iterator runtimePathProp = appOptions.find( |
| PropertyName::runtime); |
| tstring runtimePath; |
| if (runtimePathProp != appOptions.end()) { |
| runtimePath = CfgFile::asString(*runtimePathProp); |
| } else { |
| runtimePath = defaultRuntimePath; |
| LOG_TRACE(tstrings::any() |
| << "Property \"" << PropertyName::runtime.name() |
| << "\" not found in \"" << SectionName::Application.name() |
| << "\" section of launcher config file." |
| << " Using Java runtime from \"" |
| << runtimePath << "\" directory"); |
| } |
| |
| const tstring_array::const_iterator jvmLibNameEntry = std::find_if( |
| jvmLibNames.begin(), |
| jvmLibNames.end(), |
| find_jvmlib(runtimePath)); |
| |
| if (jvmLibNameEntry == jvmLibNames.end()) { |
| JP_THROW(tstrings::any() << "Failed to find JVM in \"" |
| << runtimePath |
| << "\" directory."); |
| } |
| |
| return FileUtils::mkpath() << runtimePath << *jvmLibNameEntry; |
| } |
| } // namespace |
| |
| bool AppLauncher::libEnvVariableContainsAppDir() const { |
| tstring value = SysInfo::getEnvVariable(std::nothrow, |
| libEnvVarName, tstring()); |
| #ifdef _WIN32 |
| value = tstrings::toLower(value); |
| #endif |
| |
| const tstring_array tokens = tstrings::split(value, |
| tstring(1, FileUtils::pathSeparator)); |
| return tokens.end() != std::find(tokens.begin(), tokens.end(), |
| #ifdef _WIN32 |
| tstrings::toLower(appDirPath) |
| #else |
| appDirPath |
| #endif |
| ); |
| } |
| |
| Jvm* AppLauncher::createJvmLauncher() const { |
| const tstring cfgFilePath = getCfgFilePath(); |
| |
| LOG_TRACE(tstrings::any() << "Launcher config file path: \"" |
| << cfgFilePath << "\""); |
| |
| CfgFile::Macros macros; |
| macros[_T("$APPDIR")] = appDirPath; |
| macros[_T("$BINDIR")] = FileUtils::dirname(launcherPath); |
| macros[_T("$ROOTDIR")] = imageRoot; |
| |
| CfgFile cfgFile = CfgFile::load(cfgFilePath).expandMacros(macros); |
| |
| if (!args.empty()) { |
| // Override default launcher arguments. |
| cfgFile.setPropertyValue(SectionName::ArgOptions, |
| PropertyName::arguments, args); |
| } |
| |
| std::unique_ptr<Jvm> jvm(new Jvm()); |
| |
| if (!libEnvVariableContainsAppDir()) { |
| (*jvm).addEnvVariable(libEnvVarName, SysInfo::getEnvVariable( |
| std::nothrow, libEnvVarName) |
| + FileUtils::pathSeparator |
| + appDirPath); |
| } |
| |
| (*jvm) |
| .setPath(findJvmLib(cfgFile, defaultRuntimePath, jvmLibNames)) |
| .addArgument(launcherPath); |
| |
| if (initJvmFromCmdlineOnly) { |
| tstring_array::const_iterator argIt = args.begin(); |
| const tstring_array::const_iterator argEnd = args.end(); |
| for (; argIt != argEnd; ++argIt) { |
| (*jvm).addArgument(*argIt); |
| } |
| } else { |
| (*jvm).initFromConfigFile(cfgFile); |
| } |
| |
| return jvm.release(); |
| } |
| |
| |
| void AppLauncher::launch() const { |
| std::unique_ptr<Jvm>(createJvmLauncher())->launch(); |
| } |
| |
| |
| tstring AppLauncher::getCfgFilePath() const { |
| tstring_array::const_iterator it = cfgFileLookupDirs.begin(); |
| tstring_array::const_iterator end = cfgFileLookupDirs.end(); |
| const tstring cfgFileName = FileUtils::stripExeSuffix( |
| FileUtils::basename(launcherPath)) + _T(".cfg"); |
| for (; it != end; ++it) { |
| const tstring cfgFilePath = FileUtils::mkpath() << *it << cfgFileName; |
| LOG_TRACE(tstrings::any() << "Check [" << cfgFilePath << "] file exit"); |
| if (FileUtils::isFileExists(cfgFilePath)) { |
| return cfgFilePath; |
| } |
| } |
| |
| return FileUtils::mkpath() << appDirPath << cfgFileName; |
| } |