jdk
177 строк · 5.7 Кб
1/*
2* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*
5* This code is free software; you can redistribute it and/or modify it
6* under the terms of the GNU General Public License version 2 only, as
7* published by the Free Software Foundation. Oracle designates this
8* particular file as subject to the "Classpath" exception as provided
9* by Oracle in the LICENSE file that accompanied this code.
10*
11* This code is distributed in the hope that it will be useful, but WITHOUT
12* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14* version 2 for more details (a copy is included in the LICENSE file that
15* accompanied this code).
16*
17* You should have received a copy of the GNU General Public License version
18* 2 along with this work; if not, write to the Free Software Foundation,
19* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*
21* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22* or visit www.oracle.com if you need additional information or have any
23* questions.
24*/
25
26#include <algorithm>27#include "AppLauncher.h"28#include "JvmLauncher.h"29#include "CfgFile.h"30#include "Log.h"31#include "Dll.h"32#include "Toolbox.h"33#include "SysInfo.h"34#include "FileUtils.h"35
36
37AppLauncher::AppLauncher() {38setInitJvmFromCmdlineOnly(false);39launcherPath = SysInfo::getProcessModulePath();40args = SysInfo::getCommandArgs();41}
42
43
44namespace {45
46struct find_jvmlib {47find_jvmlib(const tstring& v): runtimePath(v) {48}49
50bool operator () (const tstring& jvmLibName) const {51const tstring path = FileUtils::mkpath() << runtimePath << jvmLibName;52return FileUtils::isFileExists(path);53}54
55private:56const tstring& runtimePath;57};58
59tstring findJvmLib(const CfgFile& cfgFile, const tstring& defaultRuntimePath,60const tstring_array& jvmLibNames) {61const CfgFile::Properties& appOptions = cfgFile.getProperties(62SectionName::Application);63
64const CfgFile::Properties::const_iterator runtimePathProp = appOptions.find(65PropertyName::runtime);66tstring runtimePath;67if (runtimePathProp != appOptions.end()) {68runtimePath = CfgFile::asString(*runtimePathProp);69} else {70runtimePath = defaultRuntimePath;71LOG_TRACE(tstrings::any()72<< "Property \"" << PropertyName::runtime.name()73<< "\" not found in \"" << SectionName::Application.name()74<< "\" section of launcher config file."75<< " Using Java runtime from \""76<< runtimePath << "\" directory");77}78
79const tstring_array::const_iterator jvmLibNameEntry = std::find_if(80jvmLibNames.begin(),81jvmLibNames.end(),82find_jvmlib(runtimePath));83
84if (jvmLibNameEntry == jvmLibNames.end()) {85JP_THROW(tstrings::any() << "Failed to find JVM in \""86<< runtimePath87<< "\" directory.");88}89
90return FileUtils::mkpath() << runtimePath << *jvmLibNameEntry;91}
92} // namespace93
94bool AppLauncher::libEnvVariableContainsAppDir() const {95tstring value = SysInfo::getEnvVariable(std::nothrow,96libEnvVarName, tstring());97#ifdef _WIN3298value = tstrings::toLower(value);99#endif100
101const tstring_array tokens = tstrings::split(value,102tstring(1, FileUtils::pathSeparator));103return tokens.end() != std::find(tokens.begin(), tokens.end(),104#ifdef _WIN32105tstrings::toLower(appDirPath)106#else107appDirPath
108#endif109);110}
111
112Jvm* AppLauncher::createJvmLauncher() const {113const tstring cfgFilePath = getCfgFilePath();114
115LOG_TRACE(tstrings::any() << "Launcher config file path: \""116<< cfgFilePath << "\"");117
118CfgFile::Macros macros;119macros[_T("$APPDIR")] = appDirPath;120macros[_T("$BINDIR")] = FileUtils::dirname(launcherPath);121macros[_T("$ROOTDIR")] = imageRoot;122
123CfgFile cfgFile = CfgFile::load(cfgFilePath).expandMacros(macros);124
125if (!args.empty()) {126// Override default launcher arguments.127cfgFile.setPropertyValue(SectionName::ArgOptions,128PropertyName::arguments, args);129}130
131std::unique_ptr<Jvm> jvm(new Jvm());132
133if (!libEnvVariableContainsAppDir()) {134(*jvm).addEnvVariable(libEnvVarName, SysInfo::getEnvVariable(135std::nothrow, libEnvVarName)136+ FileUtils::pathSeparator137+ appDirPath);138}139
140(*jvm)141.setPath(findJvmLib(cfgFile, defaultRuntimePath, jvmLibNames))142.addArgument(launcherPath);143
144if (initJvmFromCmdlineOnly) {145tstring_array::const_iterator argIt = args.begin();146const tstring_array::const_iterator argEnd = args.end();147for (; argIt != argEnd; ++argIt) {148(*jvm).addArgument(*argIt);149}150} else {151(*jvm).initFromConfigFile(cfgFile);152}153
154return jvm.release();155}
156
157
158void AppLauncher::launch() const {159std::unique_ptr<Jvm>(createJvmLauncher())->launch();160}
161
162
163tstring AppLauncher::getCfgFilePath() const {164tstring_array::const_iterator it = cfgFileLookupDirs.begin();165tstring_array::const_iterator end = cfgFileLookupDirs.end();166const tstring cfgFileName = FileUtils::stripExeSuffix(167FileUtils::basename(launcherPath)) + _T(".cfg");168for (; it != end; ++it) {169const tstring cfgFilePath = FileUtils::mkpath() << *it << cfgFileName;170LOG_TRACE(tstrings::any() << "Check [" << cfgFilePath << "] file exit");171if (FileUtils::isFileExists(cfgFilePath)) {172return cfgFilePath;173}174}175
176return FileUtils::mkpath() << appDirPath << cfgFileName;177}
178