modules/fxpackager/src/main/native/library/common/main.cpp

Print this page

        

@@ -37,20 +37,24 @@
 #include "PropertyFile.h"
 #include "JavaVirtualMachine.h"
 #include "Package.h"
 #include "PlatformThread.h"
 #include "Macros.h"
+#include "Messages.h"
 
-#include "jni.h"
 
 #ifdef WINDOWS
 #include <Shellapi.h>
 #endif
 
 
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+
 /*
-This is launcher program for application packaging on Windows, Mac and Linux.
+This is the launcher program for application packaging on Windows, Mac and Linux.
 
 Basic approach:
   - Launcher executable loads packager.dll/libpackager.dylib/libpackager.so and calls start_launcher below.
   - Reads app/package.cfg or Info.plist or app/<appname>.cfg for application launch configuration
      (package.cfg is property file).

@@ -65,11 +69,10 @@
     (example: can not use custom stack size).
     Solution used by java launcher is to create a new thread to invoke JVM.
     See CR 6316197 for more information.
 */
 
-
 extern "C" {
 
 #ifdef WINDOWS
     BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
         return true;

@@ -78,43 +81,120 @@
     __declspec(dllexport)
 #endif //WINDOWS
 
     bool start_launcher(int argc, TCHAR* argv[]) {
         bool result = false;
+        bool parentProcess = true;
         
-        // Platform and Package must be initialize first.
+        // Platform must be initialize first.
         Platform& platform = Platform::GetInstance();
 
+        try {
+            platform.SetAppCDSState(cdsOn);
+
+            for (int index = 0; index < argc; index++) {
+                TString argument = argv[index];
+
+                if (argument == _T("-Xappcds:generatecache")) {
+                    platform.SetAppCDSState(cdsGenCache);
+                }
+                else if (argument == _T("-Xappcds:off")) {
+                    platform.SetAppCDSState(cdsNone);
+                }
+                else if (argument == _T("-Xapp:child")) {
+                    parentProcess = false;
+                }
 #ifdef DEBUG
-        if (argc > 1 && TString(argv[1]) == _T("-debug")) {
-#ifdef WINDOWS
-            if (::MessageBox(NULL, PlatformString(platform.GetProcessID()), _T("Would you like to debug?"), MB_OKCANCEL) != IDCANCEL) {
-#endif //WINDOWS
-#ifdef POSIX
-            printf("%s\n", PlatformString(platform.GetProcessID()).c_str());
-            fflush(stdout);
-#endif //POSIX
+//TODO There appears to be a compiler bug on Mac overloading ShowResponseMessage. Investigate.
+                else if (argument == _T("-nativedebug")) {
+                    if (platform.ShowResponseMessage(_T("Test"),
+                                                     TString(_T("Would you like to debug?\n\nProcessID: ")) +
+                                                     PlatformString(platform.GetProcessID()).toString()) == mrOK) {
                 while (platform.IsNativeDebuggerPresent() == false) {
                 }
-#ifdef WINDOWS
             }
-#endif //WINDOWS
         }
 #endif //DEBUG
+            }
 
+            // Package must be initialized after Platform is fully initialized.
         Package& package = Package::GetInstance();
         Macros::Initialize();
         package.SetCommandLineArguments(argc, argv);
         platform.SetCurrentDirectory(package.GetPackageAppDirectory());
-        JavaVirtualMachine javavm;
 
-        if (javavm.StartJVM() == true) {
-            result = true;
-            javavm.ShutdownJVM();
+            switch (platform.GetAppCDSState()) {
+                case cdsGenCache: {
+                        TString cacheDirectory = package.GetAppCDSCacheDirectory();
+
+                        if (FilePath::DirectoryExists(cacheDirectory) == false) {
+                            FilePath::CreateDirectory(cacheDirectory, true);
         }
         else {
-            platform.ShowMessage(_T("Failed to launch JVM\n"));
+                            TString cacheFileName = package.GetAppCDSCacheFileName();
+
+                            if (FilePath::FileExists(cacheFileName) == true) {
+                                FilePath::DeleteFile(cacheFileName);
+                            }
+                        }
+
+
+                        break;
+                    }
+
+                case cdsAuto: {
+                    TString cacheFileName = package.GetAppCDSCacheFileName();
+
+                    if (parentProcess == true && FilePath::FileExists(cacheFileName) == false) {
+                        AutoFreePtr<Process> process = platform.CreateProcess();
+                        std::vector<TString> args;
+                        args.push_back(_T("-Xappcds:generatecache"));
+                        args.push_back(_T("-Xapp:child"));
+                        process->Execute(platform.GetModuleFileName(), args, true);
+
+                        if (FilePath::FileExists(cacheFileName) == false) {
+                            // Cache does not exist after trying to generate it,
+                            // so run without cache.
+                            platform.SetAppCDSState(cdsNone);
+                            package.Clear();
+                            package.Initialize();
+                        }
+                    }
+
+                    break;
+                }
+
+                case cdsNone:
+                case cdsOn: {
+                    break;
+                }
+            }
+
+            // Validation
+            {
+                switch (platform.GetAppCDSState()) {
+                    case cdsOn:
+                    case cdsAuto: {
+                            TString cacheFileName = package.GetAppCDSCacheFileName();
+
+                            if (FilePath::FileExists(cacheFileName) == false) {
+                                Messages& messages = Messages::GetInstance();
+                                TString message = PlatformString::Format(messages.GetMessage(APPCDS_CACHE_FILE_NOT_FOUND), cacheFileName.data());
+                                throw FileNotFoundException(message);
+                            }
+                            break;
+                        }
+                }
+            }
+
+            TString logFileName = FilePath::IncludeTrailingSeparater(platform.GetAppDataDirectory().data()) + _T("log.txt");
+
+            // Run App
+            result = RunVM();
+        }
+        catch (FileNotFoundException &e) {
+            platform.ShowMessage(e.GetMessage());
         }
 
         return result;
     }