src/jdk.jpackage/share/native/libjpackage/Package.cpp
branchJDK-8200758-branch
changeset 57064 a7fdadf67a92
parent 57063 1fa5c73d3c5a
child 57065 2446962c555c
equal deleted inserted replaced
57063:1fa5c73d3c5a 57064:a7fdadf67a92
     1 /*
       
     2  * Copyright (c) 2014, 2018, 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 "Package.h"
       
    27 #include "Lock.h"
       
    28 #include "Helpers.h"
       
    29 #include "Macros.h"
       
    30 #include "IniFile.h"
       
    31 
       
    32 #include <assert.h>
       
    33 
       
    34 
       
    35 Package::Package(void) {
       
    36     FInitialized = false;
       
    37     Initialize();
       
    38 }
       
    39 
       
    40 TPlatformNumber StringToPercentageOfNumber(TString Value,
       
    41         TPlatformNumber Number) {
       
    42     TPlatformNumber result = 0;
       
    43     size_t percentage = atoi(PlatformString(Value.c_str()));
       
    44 
       
    45     if (percentage > 0 && Number > 0) {
       
    46         result = Number * percentage / 100;
       
    47     }
       
    48 
       
    49     return result;
       
    50 }
       
    51 
       
    52 bool Package::CheckForSingleInstance() {
       
    53     Platform& platform = Platform::GetInstance();
       
    54 #ifdef MAC
       
    55     if (platform.IsMainThread()) {
       
    56         return false;
       
    57     }
       
    58 #endif
       
    59     if (FInitialized == true) {
       
    60         // everything must be initialised at this point
       
    61         return false;
       
    62     }
       
    63     TString appName;
       
    64     TString appVersion;
       
    65     AutoFreePtr<ISectionalPropertyContainer> config =
       
    66             platform.GetConfigFile(platform.GetConfigFileName());
       
    67     std::map<TString, TString> keys = platform.GetKeys();
       
    68     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
    69             keys[APP_NAME_KEY], appName);
       
    70     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
    71             keys[CONFIG_VERSION], appVersion);
       
    72     TString singleInstance;
       
    73     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
    74             keys[CONFIG_APPLICATION_INSTANCE], singleInstance);
       
    75     if (singleInstance == _T("single")) {
       
    76         TString uniqueID = appName + FBootFields->FAppID + appVersion;
       
    77         // if another instance is running, later we can try to reactivate it
       
    78         return platform.CheckForSingleInstance(uniqueID);
       
    79     }
       
    80     return false;
       
    81 }
       
    82 
       
    83 void Package::Initialize() {
       
    84     if (FInitialized == true) {
       
    85         return;
       
    86     }
       
    87 
       
    88     Platform& platform = Platform::GetInstance();
       
    89 
       
    90     FBootFields = new PackageBootFields();
       
    91     FDebugging = dsNone;
       
    92 
       
    93     FBootFields->FPackageRootDirectory = platform.GetPackageRootDirectory();
       
    94     FBootFields->FPackageAppDirectory = platform.GetPackageAppDirectory();
       
    95     FBootFields->FPackageLauncherDirectory =
       
    96             platform.GetPackageLauncherDirectory();
       
    97     FBootFields->FAppDataDirectory = platform.GetAppDataDirectory();
       
    98 
       
    99     std::map<TString, TString> keys = platform.GetKeys();
       
   100 
       
   101     // Read from configure.cfg/Info.plist
       
   102     AutoFreePtr<ISectionalPropertyContainer> config =
       
   103             platform.GetConfigFile(platform.GetConfigFileName());
       
   104 
       
   105     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   106             keys[CONFIG_APP_ID_KEY], FBootFields->FAppID);
       
   107     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   108             keys[JPACKAGE_APP_DATA_DIR], FBootFields->FPackageAppDataDirectory);
       
   109     FBootFields->FPackageAppDataDirectory =
       
   110             FilePath::FixPathForPlatform(FBootFields->FPackageAppDataDirectory);
       
   111 
       
   112     // Main JAR.
       
   113     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   114             keys[CONFIG_MAINJAR_KEY], FBootFields->FMainJar);
       
   115     FBootFields->FMainJar =
       
   116             FilePath::IncludeTrailingSeparator(GetPackageAppDirectory())
       
   117             + FilePath::FixPathForPlatform(FBootFields->FMainJar);
       
   118 
       
   119     // Main Module.
       
   120     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   121             keys[CONFIG_MAINMODULE_KEY], FBootFields->FMainModule);
       
   122 
       
   123     // Classpath.
       
   124     // 1. If the provided class path contains main jar then only use
       
   125     //    provided class path.
       
   126     // 2. If class path provided by config file is empty then add main jar.
       
   127     // 3. If main jar is not in provided class path then add it.
       
   128     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   129             keys[CONFIG_CLASSPATH_KEY], FBootFields->FClassPath);
       
   130     FBootFields->FClassPath =
       
   131             FilePath::FixPathSeparatorForPlatform(FBootFields->FClassPath);
       
   132 
       
   133     if (FBootFields->FClassPath.empty() == true) {
       
   134         FBootFields->FClassPath = GetMainJar();
       
   135     } else if (FBootFields->FClassPath.find(GetMainJar()) == TString::npos) {
       
   136         FBootFields->FClassPath = GetMainJar()
       
   137                 + FilePath::PathSeparator() + FBootFields->FClassPath;
       
   138     }
       
   139 
       
   140     // Modulepath.
       
   141     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   142             keys[CONFIG_MODULEPATH_KEY], FBootFields->FModulePath);
       
   143     FBootFields->FModulePath =
       
   144             FilePath::FixPathSeparatorForPlatform(FBootFields->FModulePath);
       
   145 
       
   146     // Main Class.
       
   147     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   148             keys[CONFIG_MAINCLASSNAME_KEY], FBootFields->FMainClassName);
       
   149 
       
   150     // Splash Screen.
       
   151     if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   152             keys[CONFIG_SPLASH_KEY],
       
   153             FBootFields->FSplashScreenFileName) == true) {
       
   154         FBootFields->FSplashScreenFileName =
       
   155             FilePath::IncludeTrailingSeparator(GetPackageAppDirectory())
       
   156             + FilePath::FixPathForPlatform(FBootFields->FSplashScreenFileName);
       
   157 
       
   158         if (FilePath::FileExists(FBootFields->FSplashScreenFileName) == false) {
       
   159             FBootFields->FSplashScreenFileName = _T("");
       
   160         }
       
   161     }
       
   162 
       
   163     // Runtime.
       
   164     config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   165             keys[JVM_RUNTIME_KEY], FBootFields->FJVMRuntimeDirectory);
       
   166 
       
   167     // Read jvmargs.
       
   168     PromoteAppCDSState(config);
       
   169     ReadJVMArgs(config);
       
   170 
       
   171     // Read args if none were passed in.
       
   172     if (FBootFields->FArgs.size() == 0) {
       
   173         OrderedMap<TString, TString> args;
       
   174 
       
   175         if (config->GetSection(keys[CONFIG_SECTION_ARGOPTIONS], args) == true) {
       
   176             FBootFields->FArgs = Helpers::MapToNameValueList(args);
       
   177         }
       
   178     }
       
   179 
       
   180     // Auto Memory.
       
   181     TString autoMemory;
       
   182 
       
   183     if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   184             keys[CONFIG_APP_MEMORY], autoMemory) == true) {
       
   185         if (autoMemory == _T("auto") || autoMemory == _T("100%")) {
       
   186             FBootFields->FMemoryState = PackageBootFields::msAuto;
       
   187             FBootFields->FMemorySize = platform.GetMemorySize();
       
   188         } else if (autoMemory.length() == 2 && isdigit(autoMemory[0]) &&
       
   189                 autoMemory[1] == '%') {
       
   190             FBootFields->FMemoryState = PackageBootFields::msAuto;
       
   191             FBootFields->FMemorySize =
       
   192                     StringToPercentageOfNumber(autoMemory.substr(0, 1),
       
   193                     platform.GetMemorySize());
       
   194         } else if (autoMemory.length() == 3 && isdigit(autoMemory[0]) &&
       
   195                 isdigit(autoMemory[1]) && autoMemory[2] == '%') {
       
   196             FBootFields->FMemoryState = PackageBootFields::msAuto;
       
   197             FBootFields->FMemorySize =
       
   198                     StringToPercentageOfNumber(autoMemory.substr(0, 2),
       
   199                     platform.GetMemorySize());
       
   200         } else {
       
   201             FBootFields->FMemoryState = PackageBootFields::msManual;
       
   202             FBootFields->FMemorySize = 0;
       
   203         }
       
   204     }
       
   205 
       
   206     // Debug
       
   207     TString debug;
       
   208     if (config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   209             keys[CONFIG_APP_DEBUG], debug) == true) {
       
   210         FBootFields->FArgs.push_back(debug);
       
   211     }
       
   212 }
       
   213 
       
   214 void Package::Clear() {
       
   215     FreeBootFields();
       
   216     FInitialized = false;
       
   217 }
       
   218 
       
   219 // This is the only location that the AppCDS state should be modified except
       
   220 // by command line arguments provided by the user.
       
   221 //
       
   222 // The state of AppCDS is as follows:
       
   223 //
       
   224 // -> cdsUninitialized
       
   225 //    -> cdsGenCache If -Xappcds:generatecache
       
   226 //    -> cdsDisabled If -Xappcds:off
       
   227 //    -> cdsEnabled If "AppCDSJVMOptions" section is present
       
   228 //    -> cdsAuto If "AppCDSJVMOptions" section is present and
       
   229 //               app.appcds.cache=auto
       
   230 //    -> cdsDisabled Default
       
   231 //
       
   232 void Package::PromoteAppCDSState(ISectionalPropertyContainer* Config) {
       
   233     Platform& platform = Platform::GetInstance();
       
   234     std::map<TString, TString> keys = platform.GetKeys();
       
   235 
       
   236     // The AppCDS state can change at this point.
       
   237     switch (platform.GetAppCDSState()) {
       
   238         case cdsEnabled:
       
   239         case cdsAuto:
       
   240         case cdsDisabled:
       
   241         case cdsGenCache: {
       
   242             // Do nothing.
       
   243             break;
       
   244         }
       
   245 
       
   246         case cdsUninitialized: {
       
   247             if (Config->ContainsSection(
       
   248                     keys[CONFIG_SECTION_APPCDSJVMOPTIONS]) == true) {
       
   249                 // If the AppCDS section is present then enable AppCDS.
       
   250                 TString appCDSCacheValue;
       
   251 
       
   252                 // If running with AppCDS enabled, and the configuration has
       
   253                 // been setup so "auto" is enabled, then
       
   254                 // the launcher will attempt to generate the cache file
       
   255                 // automatically and run the application.
       
   256                 if (Config->GetValue(keys[CONFIG_SECTION_APPLICATION],
       
   257                         _T("app.appcds.cache"), appCDSCacheValue) == true &&
       
   258                     appCDSCacheValue == _T("auto")) {
       
   259                     platform.SetAppCDSState(cdsAuto);
       
   260                 }
       
   261                 else {
       
   262                     platform.SetAppCDSState(cdsEnabled);
       
   263                 }
       
   264             } else {
       
   265 
       
   266                 platform.SetAppCDSState(cdsDisabled);
       
   267             }
       
   268         }
       
   269     }
       
   270 }
       
   271 
       
   272 void Package::ReadJVMArgs(ISectionalPropertyContainer* Config) {
       
   273     Platform& platform = Platform::GetInstance();
       
   274     std::map<TString, TString> keys = platform.GetKeys();
       
   275 
       
   276     // Evaluate based on the current AppCDS state.
       
   277     switch (platform.GetAppCDSState()) {
       
   278         case cdsUninitialized: {
       
   279             throw Exception(_T("Internal Error"));
       
   280         }
       
   281 
       
   282         case cdsDisabled: {
       
   283             Config->GetSection(keys[CONFIG_SECTION_JVMOPTIONS],
       
   284                     FBootFields->FJVMArgs);
       
   285             break;
       
   286         }
       
   287 
       
   288         case cdsGenCache: {
       
   289             Config->GetSection(keys[
       
   290                     CONFIG_SECTION_APPCDSGENERATECACHEJVMOPTIONS],
       
   291                     FBootFields->FJVMArgs);
       
   292             break;
       
   293         }
       
   294 
       
   295         case cdsAuto:
       
   296         case cdsEnabled: {
       
   297             if (Config->GetValue(keys[CONFIG_SECTION_APPCDSJVMOPTIONS],
       
   298                     _T( "-XX:SharedArchiveFile"),
       
   299                     FBootFields->FAppCDSCacheFileName) == true) {
       
   300                 // File names may contain the incorrect path separators.
       
   301                 // The cache file name must be corrected at this point.
       
   302                 if (FBootFields->FAppCDSCacheFileName.empty() == false) {
       
   303                     IniFile* iniConfig = dynamic_cast<IniFile*>(Config);
       
   304 
       
   305                     if (iniConfig != NULL) {
       
   306                         FBootFields->FAppCDSCacheFileName =
       
   307                                 FilePath::FixPathForPlatform(
       
   308                                 FBootFields->FAppCDSCacheFileName);
       
   309                         iniConfig->SetValue(keys[
       
   310                                 CONFIG_SECTION_APPCDSJVMOPTIONS],
       
   311                                 _T( "-XX:SharedArchiveFile"),
       
   312                                 FBootFields->FAppCDSCacheFileName);
       
   313                     }
       
   314                 }
       
   315 
       
   316                 Config->GetSection(keys[CONFIG_SECTION_APPCDSJVMOPTIONS],
       
   317                         FBootFields->FJVMArgs);
       
   318             }
       
   319 
       
   320             break;
       
   321         }
       
   322     }
       
   323 }
       
   324 
       
   325 void Package::SetCommandLineArguments(int argc, TCHAR* argv[]) {
       
   326     if (argc > 0) {
       
   327         std::list<TString> args;
       
   328 
       
   329         // Prepare app arguments. Skip value at index 0 -
       
   330         // this is path to executable.
       
   331         FBootFields->FCommandName = argv[0];
       
   332 
       
   333         // Path to executable is at 0 index so start at index 1.
       
   334         for (int index = 1; index < argc; index++) {
       
   335             TString arg = argv[index];
       
   336 
       
   337 #ifdef DEBUG
       
   338             if (arg == _T("-debug")) {
       
   339                 FDebugging = dsNative;
       
   340             }
       
   341 
       
   342             if (arg == _T("-javadebug")) {
       
   343                 FDebugging = dsJava;
       
   344             }
       
   345 #endif //DEBUG
       
   346 #ifdef MAC
       
   347             if (arg.find(_T("-psn_"), 0) != TString::npos) {
       
   348                 Platform& platform = Platform::GetInstance();
       
   349 
       
   350                 if (platform.IsMainThread() == true) {
       
   351 #ifdef DEBUG
       
   352                     printf("%s\n", arg.c_str());
       
   353 #endif //DEBUG
       
   354                     continue;
       
   355                 }
       
   356             }
       
   357 
       
   358             if (arg == _T("-NSDocumentRevisionsDebugMode")) {
       
   359                 // Ignore -NSDocumentRevisionsDebugMode and
       
   360                 // the following YES/NO
       
   361                 index++;
       
   362                 continue;
       
   363             }
       
   364 #endif //MAC
       
   365 
       
   366             args.push_back(arg);
       
   367         }
       
   368 
       
   369         if (args.size() > 0) {
       
   370             FBootFields->FArgs = args;
       
   371         }
       
   372     }
       
   373 }
       
   374 
       
   375 Package& Package::GetInstance() {
       
   376     static Package instance;
       
   377     // Guaranteed to be destroyed. Instantiated on first use.
       
   378     return instance;
       
   379 }
       
   380 
       
   381 Package::~Package(void) {
       
   382     FreeBootFields();
       
   383 }
       
   384 
       
   385 void Package::FreeBootFields() {
       
   386     if (FBootFields != NULL) {
       
   387         delete FBootFields;
       
   388         FBootFields = NULL;
       
   389     }
       
   390 }
       
   391 
       
   392 OrderedMap<TString, TString> Package::GetJVMArgs() {
       
   393     return FBootFields->FJVMArgs;
       
   394 }
       
   395 
       
   396 std::vector<TString> GetKeysThatAreNotDuplicates(OrderedMap<TString,
       
   397         TString> &Defaults, OrderedMap<TString, TString> &Overrides) {
       
   398     std::vector<TString> result;
       
   399     std::vector<TString> overrideKeys = Overrides.GetKeys();
       
   400 
       
   401     for (size_t index = 0; index < overrideKeys.size(); index++) {
       
   402         TString overridesKey = overrideKeys[index];
       
   403         TString overridesValue;
       
   404         TString defaultValue;
       
   405 
       
   406         if ((Defaults.ContainsKey(overridesKey) == false) ||
       
   407            (Defaults.GetValue(overridesKey, defaultValue) == true &&
       
   408             Overrides.GetValue(overridesKey, overridesValue) == true &&
       
   409             defaultValue != overridesValue)) {
       
   410             result.push_back(overridesKey);
       
   411         }
       
   412     }
       
   413 
       
   414     return result;
       
   415 }
       
   416 
       
   417 OrderedMap<TString, TString> CreateOrderedMapFromKeyList(OrderedMap<TString,
       
   418         TString> &Map, std::vector<TString> &Keys) {
       
   419     OrderedMap<TString, TString> result;
       
   420 
       
   421     for (size_t index = 0; index < Keys.size(); index++) {
       
   422         TString key = Keys[index];
       
   423         TString value;
       
   424 
       
   425         if (Map.GetValue(key, value) == true) {
       
   426             result.Append(key, value);
       
   427         }
       
   428     }
       
   429 
       
   430     return result;
       
   431 }
       
   432 
       
   433 std::vector<TString> GetKeysThatAreNotOverridesOfDefaultValues(
       
   434         OrderedMap<TString, TString> &Defaults, OrderedMap<TString,
       
   435         TString> &Overrides) {
       
   436     std::vector<TString> result;
       
   437     std::vector<TString> keys = Overrides.GetKeys();
       
   438 
       
   439     for (unsigned int index = 0; index< keys.size(); index++) {
       
   440         TString key = keys[index];
       
   441 
       
   442         if (Defaults.ContainsKey(key) == true) {
       
   443             try {
       
   444                 TString value = Overrides[key];
       
   445                 Defaults[key] = value;
       
   446             }
       
   447             catch (std::out_of_range) {
       
   448             }
       
   449         }
       
   450         else {
       
   451             result.push_back(key);
       
   452         }
       
   453     }
       
   454 
       
   455     return result;
       
   456 }
       
   457 
       
   458 std::list<TString> Package::GetArgs() {
       
   459     assert(FBootFields != NULL);
       
   460     return FBootFields->FArgs;
       
   461 }
       
   462 
       
   463 TString Package::GetPackageRootDirectory() {
       
   464     assert(FBootFields != NULL);
       
   465     return FBootFields->FPackageRootDirectory;
       
   466 }
       
   467 
       
   468 TString Package::GetPackageAppDirectory() {
       
   469     assert(FBootFields != NULL);
       
   470     return FBootFields->FPackageAppDirectory;
       
   471 }
       
   472 
       
   473 TString Package::GetPackageLauncherDirectory() {
       
   474     assert(FBootFields != NULL);
       
   475     return FBootFields->FPackageLauncherDirectory;
       
   476 }
       
   477 
       
   478 TString Package::GetAppDataDirectory() {
       
   479     assert(FBootFields != NULL);
       
   480     return FBootFields->FAppDataDirectory;
       
   481 }
       
   482 
       
   483 TString Package::GetAppCDSCacheDirectory() {
       
   484     if (FAppCDSCacheDirectory.empty()) {
       
   485         Platform& platform = Platform::GetInstance();
       
   486         FAppCDSCacheDirectory = FilePath::IncludeTrailingSeparator(
       
   487                 platform.GetAppDataDirectory())
       
   488                 + FilePath::IncludeTrailingSeparator(
       
   489                 GetPackageAppDataDirectory()) + _T("cache");
       
   490 
       
   491         Macros& macros = Macros::GetInstance();
       
   492         FAppCDSCacheDirectory = macros.ExpandMacros(FAppCDSCacheDirectory);
       
   493         FAppCDSCacheDirectory =
       
   494                 FilePath::FixPathForPlatform(FAppCDSCacheDirectory);
       
   495     }
       
   496 
       
   497     return FAppCDSCacheDirectory;
       
   498 }
       
   499 
       
   500 TString Package::GetAppCDSCacheFileName() {
       
   501     assert(FBootFields != NULL);
       
   502 
       
   503     if (FBootFields->FAppCDSCacheFileName.empty() == false) {
       
   504         Macros& macros = Macros::GetInstance();
       
   505         FBootFields->FAppCDSCacheFileName =
       
   506                 macros.ExpandMacros(FBootFields->FAppCDSCacheFileName);
       
   507         FBootFields->FAppCDSCacheFileName =
       
   508                 FilePath::FixPathForPlatform(FBootFields->FAppCDSCacheFileName);
       
   509     }
       
   510 
       
   511     return FBootFields->FAppCDSCacheFileName;
       
   512 }
       
   513 
       
   514 TString Package::GetAppID() {
       
   515     assert(FBootFields != NULL);
       
   516     return FBootFields->FAppID;
       
   517 }
       
   518 
       
   519 TString Package::GetPackageAppDataDirectory() {
       
   520     assert(FBootFields != NULL);
       
   521     return FBootFields->FPackageAppDataDirectory;
       
   522 }
       
   523 
       
   524 TString Package::GetClassPath() {
       
   525     assert(FBootFields != NULL);
       
   526     return FBootFields->FClassPath;
       
   527 }
       
   528 
       
   529 TString Package::GetModulePath() {
       
   530     assert(FBootFields != NULL);
       
   531     return FBootFields->FModulePath;
       
   532 }
       
   533 
       
   534 TString Package::GetMainJar() {
       
   535     assert(FBootFields != NULL);
       
   536     return FBootFields->FMainJar;
       
   537 }
       
   538 
       
   539 TString Package::GetMainModule() {
       
   540     assert(FBootFields != NULL);
       
   541     return FBootFields->FMainModule;
       
   542 }
       
   543 
       
   544 TString Package::GetMainClassName() {
       
   545     assert(FBootFields != NULL);
       
   546     return FBootFields->FMainClassName;
       
   547 }
       
   548 
       
   549 TString Package::GetJVMLibraryFileName() {
       
   550     assert(FBootFields != NULL);
       
   551 
       
   552     if (FBootFields->FJVMLibraryFileName.empty() == true) {
       
   553         Platform& platform = Platform::GetInstance();
       
   554         Macros& macros = Macros::GetInstance();
       
   555         TString jvmRuntimePath = macros.ExpandMacros(GetJVMRuntimeDirectory());
       
   556         FBootFields->FJVMLibraryFileName =
       
   557                 platform.GetBundledJVMLibraryFileName(jvmRuntimePath);
       
   558     }
       
   559 
       
   560     return FBootFields->FJVMLibraryFileName;
       
   561 }
       
   562 
       
   563 TString Package::GetJVMRuntimeDirectory() {
       
   564     assert(FBootFields != NULL);
       
   565     return FBootFields->FJVMRuntimeDirectory;
       
   566 }
       
   567 
       
   568 TString Package::GetSplashScreenFileName() {
       
   569     assert(FBootFields != NULL);
       
   570     return FBootFields->FSplashScreenFileName;
       
   571 }
       
   572 
       
   573 bool Package::HasSplashScreen() {
       
   574     assert(FBootFields != NULL);
       
   575     return FilePath::FileExists(FBootFields->FSplashScreenFileName);
       
   576 }
       
   577 
       
   578 TString Package::GetCommandName() {
       
   579     assert(FBootFields != NULL);
       
   580     return FBootFields->FCommandName;
       
   581 }
       
   582 
       
   583 TPlatformNumber Package::GetMemorySize() {
       
   584     assert(FBootFields != NULL);
       
   585     return FBootFields->FMemorySize;
       
   586 }
       
   587 
       
   588 PackageBootFields::MemoryState Package::GetMemoryState() {
       
   589     assert(FBootFields != NULL);
       
   590     return FBootFields->FMemoryState;
       
   591 }
       
   592 
       
   593 DebugState Package::Debugging() {
       
   594     return FDebugging;
       
   595 }