src/jdk.jpackage/share/native/libapplauncher/main.cpp
branchJDK-8200758-branch
changeset 58994 b09ba68c6a19
parent 58993 b5e1baa9d2c3
child 58995 de1413ae214c
equal deleted inserted replaced
58993:b5e1baa9d2c3 58994:b09ba68c6a19
     1 /*
       
     2  * Copyright (c) 2014, 2019, 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 "Platform.h"
       
    27 #include "PlatformString.h"
       
    28 #include "FilePath.h"
       
    29 #include "PropertyFile.h"
       
    30 #include "JavaVirtualMachine.h"
       
    31 #include "Package.h"
       
    32 #include "Macros.h"
       
    33 #include "Messages.h"
       
    34 
       
    35 #include <stdio.h>
       
    36 #include <signal.h>
       
    37 #include <stdlib.h>
       
    38 
       
    39 /*
       
    40 This is the app launcher program for application packaging on Windows, Mac,
       
    41     and Linux.
       
    42 
       
    43 Basic approach:
       
    44   - Launcher (jpackageapplauncher) is executable that loads
       
    45     applauncher.dll/libapplauncher.dylib/libapplauncher.so
       
    46     and calls start_launcher below.
       
    47   - Reads app/package.cfg or Info.plist or app/<appname>.cfg for application
       
    48     launch configuration (package.cfg is property file).
       
    49   - Load Java with requested Java settings (bundled client Java if availble,
       
    50     server or installed Java otherwise).
       
    51   - Wait for Java to exit and then exit from Main
       
    52   - To debug application by passing command line argument.
       
    53   - Application folder is added to the library path (so LoadLibrary()) works.
       
    54 
       
    55 Limitations and future work:
       
    56   - Running Java code in primordial thread may cause problems
       
    57     (example: can not use custom stack size).
       
    58     Solution used by java launcher is to create a new thread to invoke Java.
       
    59     See CR 6316197 for more information.
       
    60 */
       
    61 
       
    62 extern "C" {
       
    63 
       
    64     JNIEXPORT bool start_launcher(int argc, TCHAR* argv[]) {
       
    65         bool result = false;
       
    66         bool parentProcess = true;
       
    67 
       
    68         // Platform must be initialize first.
       
    69         Platform& platform = Platform::GetInstance();
       
    70 
       
    71         try {
       
    72             for (int index = 0; index < argc; index++) {
       
    73                 TString argument = argv[index];
       
    74 
       
    75                 if (argument == _T("-Xappcds:generatecache")) {
       
    76                     platform.SetAppCDSState(cdsGenCache);
       
    77                 }
       
    78                 else if (argument == _T("-Xappcds:off")) {
       
    79                     platform.SetAppCDSState(cdsDisabled);
       
    80                 }
       
    81                 else if (argument == _T("-Xapp:child")) {
       
    82                     parentProcess = false;
       
    83                 }
       
    84             }
       
    85 
       
    86             // Package must be initialized after Platform is fully initialized.
       
    87             Package& package = Package::GetInstance();
       
    88             Macros::Initialize();
       
    89             package.SetCommandLineArguments(argc, argv);
       
    90 
       
    91             switch (platform.GetAppCDSState()) {
       
    92                 case cdsDisabled:
       
    93                 case cdsUninitialized:
       
    94                 case cdsEnabled: {
       
    95                     break;
       
    96                 }
       
    97 
       
    98                 case cdsGenCache: {
       
    99                     TString cacheDirectory = package.GetAppCDSCacheDirectory();
       
   100 
       
   101                     if (FilePath::DirectoryExists(cacheDirectory) == false) {
       
   102                         FilePath::CreateDirectory(cacheDirectory, true);
       
   103                     } else {
       
   104                         TString cacheFileName =
       
   105                                 package.GetAppCDSCacheFileName();
       
   106                         if (FilePath::FileExists(cacheFileName) == true) {
       
   107                             FilePath::DeleteFile(cacheFileName);
       
   108                         }
       
   109                     }
       
   110 
       
   111                     break;
       
   112                 }
       
   113 
       
   114                 case cdsAuto: {
       
   115                     TString cacheFileName = package.GetAppCDSCacheFileName();
       
   116 
       
   117                     if (parentProcess == true &&
       
   118                             FilePath::FileExists(cacheFileName) == false) {
       
   119                         AutoFreePtr<Process> process = platform.CreateProcess();
       
   120                         std::vector<TString> args;
       
   121                         args.push_back(_T("-Xappcds:generatecache"));
       
   122                         args.push_back(_T("-Xapp:child"));
       
   123                         process->Execute(
       
   124                                 platform.GetModuleFileName(), args, true);
       
   125 
       
   126                         if (FilePath::FileExists(cacheFileName) == false) {
       
   127                             // Cache does not exist after trying to generate it,
       
   128                             // so run without cache.
       
   129                             platform.SetAppCDSState(cdsDisabled);
       
   130                             package.Clear();
       
   131                             package.Initialize();
       
   132                         }
       
   133                     }
       
   134 
       
   135                     break;
       
   136                 }
       
   137             }
       
   138 
       
   139             // Validation
       
   140             switch (platform.GetAppCDSState()) {
       
   141                 case cdsDisabled:
       
   142                 case cdsGenCache: {
       
   143                     // Do nothing.
       
   144                     break;
       
   145                 }
       
   146 
       
   147                 case cdsEnabled:
       
   148                 case cdsAuto: {
       
   149                     TString cacheFileName =
       
   150                             package.GetAppCDSCacheFileName();
       
   151 
       
   152                     if (FilePath::FileExists(cacheFileName) == false) {
       
   153                         Messages& messages = Messages::GetInstance();
       
   154                         TString message = PlatformString::Format(
       
   155                                 messages.GetMessage(
       
   156                                 APPCDS_CACHE_FILE_NOT_FOUND),
       
   157                                 cacheFileName.data());
       
   158                         throw Exception(message);
       
   159                     }
       
   160                     break;
       
   161                 }
       
   162 
       
   163                 case cdsUninitialized: {
       
   164                     platform.ShowMessage(_T("Internal Error"));
       
   165                     break;
       
   166                 }
       
   167             }
       
   168 
       
   169             // Run App
       
   170             result = RunVM();
       
   171         } catch (Exception &e) {
       
   172             platform.ShowMessage(e.GetMessage());
       
   173         }
       
   174 
       
   175         return result;
       
   176     }
       
   177 
       
   178     JNIEXPORT void stop_launcher() {
       
   179     }
       
   180 }