1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 
  33 
  34 #include "Platform.h"
  35 #include "PlatformString.h"
  36 #include "FilePath.h"
  37 #include "PropertyFile.h"
  38 #include "JavaVirtualMachine.h"
  39 #include "Package.h"
  40 #include "PlatformThread.h"
  41 #include "Macros.h"
  42 
  43 #include "jni.h"
  44 
  45 #ifdef WINDOWS
  46 #include <Shellapi.h>
  47 #endif
  48 
  49 
  50 /*
  51 This is launcher program for application packaging on Windows, Mac and Linux.
  52 
  53 Basic approach:
  54   - Launcher executable loads packager.dll/libpackager.dylib/libpackager.so and calls start_launcher below.
  55   - Reads app/package.cfg or Info.plist or app/<appname>.cfg for application launch configuration
  56      (package.cfg is property file).
  57   - Load JVM with requested JVM settings (bundled client JVM if availble, server or installed JVM otherwise).
  58   - Wait for JVM to exit and then exit from Main
  59   - To debug application by set env variable (TODO) or pass "/Debug" option on command line.
  60   - TODO: default directory is set to user's Documents and Settings.
  61   - Application folder is added to the library path (so LoadLibrary()) works.
  62 
  63 Limitations and future work:
  64   - Running Java code in primordial thread may cause problems
  65     (example: can not use custom stack size).
  66     Solution used by java launcher is to create a new thread to invoke JVM.
  67     See CR 6316197 for more information.
  68 */
  69 
  70 
  71 extern "C" {
  72 
  73 #ifdef WINDOWS
  74     BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
  75         return true;
  76     }
  77 
  78     __declspec(dllexport)
  79 #endif //WINDOWS
  80 
  81     bool start_launcher(int argc, TCHAR* argv[]) {
  82         bool result = false;
  83         
  84         // Platform and Package must be initialize first.
  85         Platform& platform = Platform::GetInstance();
  86 
  87 #ifdef DEBUG
  88         if (argc > 1 && TString(argv[1]) == _T("-debug")) {
  89 #ifdef WINDOWS
  90             if (::MessageBox(NULL, PlatformString(platform.GetProcessID()), _T("Would you like to debug?"), MB_OKCANCEL) != IDCANCEL) {
  91 #endif //WINDOWS
  92 #ifdef POSIX
  93             printf("%s\n", PlatformString(platform.GetProcessID()).c_str());
  94             fflush(stdout);
  95 #endif //POSIX
  96                 while (platform.IsNativeDebuggerPresent() == false) {
  97                 }
  98 #ifdef WINDOWS
  99             }
 100 #endif //WINDOWS
 101         }
 102 #endif //DEBUG
 103 
 104         Package& package = Package::GetInstance();
 105         Macros::Initialize();
 106         package.SetCommandLineArguments(argc, argv);
 107         platform.SetCurrentDirectory(package.GetPackageAppDirectory());
 108         JavaVirtualMachine javavm;
 109 
 110         if (javavm.StartJVM() == true) {
 111             result = true;
 112             javavm.ShutdownJVM();
 113         }
 114         else {
 115             platform.ShowMessage(_T("Failed to launch JVM\n"));
 116         }
 117 
 118         return result;
 119     }
 120     
 121     void stop_launcher() {
 122     }
 123 }