src/share/bin/java.c

Print this page


   1 /*
   2  * Copyright (c) 1995, 2012, 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


 132     VM_ERROR,
 133     VM_IF_SERVER_CLASS,
 134     VM_IGNORE
 135 };
 136 
 137 struct vmdesc {
 138     char *name;
 139     int flag;
 140     char *alias;
 141     char *server_class;
 142 };
 143 static struct vmdesc *knownVMs = NULL;
 144 static int knownVMsCount = 0;
 145 static int knownVMsLimit = 0;
 146 
 147 static void GrowKnownVMs();
 148 static int  KnownVMIndex(const char* name);
 149 static void FreeKnownVMs();
 150 static jboolean IsWildCardEnabled();
 151 
 152 #define ARG_CHECK(n, f, a) if (n < 1) { \
 153     JLI_ReportErrorMessage(f, a); \


 154     printUsage = JNI_TRUE; \
 155     *pret = 1; \
 156     return JNI_TRUE; \
 157 }

 158 
 159 /*
 160  * Running Java code in primordial thread caused many problems. We will
 161  * create a new thread to invoke JVM. See 6316197 for more information.
 162  */
 163 static jlong threadStackSize    = 0;  /* stack size of the new thread */
 164 static jlong maxHeapSize        = 0;  /* max heap size */
 165 static jlong initialHeapSize    = 0;  /* inital heap size */
 166 
 167 /*
 168  * Entry point.
 169  */
 170 int
 171 JLI_Launch(int argc, char ** argv,              /* main argc, argc */
 172         int jargc, const char** jargv,          /* java args */
 173         int appclassc, const char** appclassv,  /* app classpath */
 174         const char* fullversion,                /* full version defined */
 175         const char* dotversion,                 /* dot version defined */
 176         const char* pname,                      /* program name */
 177         const char* lname,                      /* launcher name */


 293     /* set the -Dsun.java.launcher.* platform properties */
 294     SetJavaLauncherPlatformProps();
 295 
 296     return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);
 297 }
 298 /*
 299  * Always detach the main thread so that it appears to have ended when
 300  * the application's main method exits.  This will invoke the
 301  * uncaught exception handler machinery if main threw an
 302  * exception.  An uncaught exception handler cannot change the
 303  * launcher's return code except by calling System.exit.
 304  *
 305  * Wait for all non-daemon threads to end, then destroy the VM.
 306  * This will actually create a trivial new Java waiter thread
 307  * named "DestroyJavaVM", but this will be seen as a different
 308  * thread from the one that executed main, even though they are
 309  * the same C thread.  This allows mainThread.join() and
 310  * mainThread.isAlive() to work as expected.
 311  */
 312 #define LEAVE() \
 313     if ((*vm)->DetachCurrentThread(vm) != 0) { \

 314         JLI_ReportErrorMessage(JVM_ERROR2); \
 315         ret = 1; \
 316     } \

 317     (*vm)->DestroyJavaVM(vm); \
 318     return ret \


 319 
 320 #define CHECK_EXCEPTION_NULL_LEAVE(e) \

 321     if ((*env)->ExceptionOccurred(env)) { \
 322         JLI_ReportExceptionDescription(env); \
 323         LEAVE(); \
 324     } \
 325     if ((e) == NULL) { \
 326         JLI_ReportErrorMessage(JNI_ERROR); \
 327         LEAVE(); \
 328     }

 329 
 330 #define CHECK_EXCEPTION_LEAVE(rv) \

 331     if ((*env)->ExceptionOccurred(env)) { \
 332         JLI_ReportExceptionDescription(env); \
 333         ret = (rv); \
 334         LEAVE(); \
 335     }

 336 
 337 int JNICALL
 338 JavaMain(void * _args)
 339 {
 340     JavaMainArgs *args = (JavaMainArgs *)_args;
 341     int argc = args->argc;
 342     char **argv = args->argv;
 343     int mode = args->mode;
 344     char *what = args->what;
 345     InvocationFunctions ifn = args->ifn;
 346 
 347     JavaVM *vm = 0;
 348     JNIEnv *env = 0;
 349     jclass mainClass = NULL;
 350     jclass appClass = NULL; // actual application class being launched
 351     jmethodID mainID;
 352     jobjectArray mainArgs;
 353     int ret = 0;
 354     jlong start, end;
 355 


 417      *
 418      * Hence, future work should either:
 419      *     1)   Correct the local parsing code and verify that the
 420      *          Main-Class attribute gets properly passed through
 421      *          all environments,
 422      *     2)   Remove the vestages of maintaining main_class through
 423      *          the environment (and remove these comments).
 424      *
 425      * This method also correctly handles launching existing JavaFX
 426      * applications that may or may not have a Main-Class manifest entry.
 427      */
 428     mainClass = LoadMainClass(env, mode, what);
 429     CHECK_EXCEPTION_NULL_LEAVE(mainClass);
 430     /*
 431      * In some cases when launching an application that needs a helper, e.g., a
 432      * JavaFX application with no main method, the mainClass will not be the
 433      * applications own main class but rather a helper class. To keep things
 434      * consistent in the UI we need to track and report the application main class.
 435      */
 436     appClass = GetApplicationClass(env);
 437     NULL_CHECK(appClass);
 438     /*
 439      * PostJVMInit uses the class name as the application name for GUI purposes,
 440      * for example, on OSX this sets the application name in the menu bar for
 441      * both SWT and JavaFX. So we'll pass the actual application class here
 442      * instead of mainClass as that may be a launcher or helper class instead
 443      * of the application class.
 444      */
 445     PostJVMInit(env, appClass, vm);
 446     /*
 447      * The LoadMainClass not only loads the main class, it will also ensure
 448      * that the main method's signature is correct, therefore further checking
 449      * is not required. The main method is invoked here so that extraneous java
 450      * stacks are not in the application stack trace.
 451      */
 452     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
 453                                        "([Ljava/lang/String;)V");
 454     CHECK_EXCEPTION_NULL_LEAVE(mainID);
 455 
 456     /* Build platform specific argument array */
 457     mainArgs = CreateApplicationArgs(env, argv, argc);


   1 /*
   2  * Copyright (c) 1995, 2013, 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


 132     VM_ERROR,
 133     VM_IF_SERVER_CLASS,
 134     VM_IGNORE
 135 };
 136 
 137 struct vmdesc {
 138     char *name;
 139     int flag;
 140     char *alias;
 141     char *server_class;
 142 };
 143 static struct vmdesc *knownVMs = NULL;
 144 static int knownVMsCount = 0;
 145 static int knownVMsLimit = 0;
 146 
 147 static void GrowKnownVMs();
 148 static int  KnownVMIndex(const char* name);
 149 static void FreeKnownVMs();
 150 static jboolean IsWildCardEnabled();
 151 
 152 #define ARG_CHECK(AC_arg_count, AC_failure_message, AC_questionable_arg) \
 153     do { \
 154         if (AC_arg_count < 1) { \
 155             JLI_ReportErrorMessage(AC_failure_message, AC_questionable_arg); \
 156             printUsage = JNI_TRUE; \
 157             *pret = 1; \
 158             return JNI_TRUE; \
 159         } \
 160     } while (JNI_FALSE)
 161 
 162 /*
 163  * Running Java code in primordial thread caused many problems. We will
 164  * create a new thread to invoke JVM. See 6316197 for more information.
 165  */
 166 static jlong threadStackSize    = 0;  /* stack size of the new thread */
 167 static jlong maxHeapSize        = 0;  /* max heap size */
 168 static jlong initialHeapSize    = 0;  /* inital heap size */
 169 
 170 /*
 171  * Entry point.
 172  */
 173 int
 174 JLI_Launch(int argc, char ** argv,              /* main argc, argc */
 175         int jargc, const char** jargv,          /* java args */
 176         int appclassc, const char** appclassv,  /* app classpath */
 177         const char* fullversion,                /* full version defined */
 178         const char* dotversion,                 /* dot version defined */
 179         const char* pname,                      /* program name */
 180         const char* lname,                      /* launcher name */


 296     /* set the -Dsun.java.launcher.* platform properties */
 297     SetJavaLauncherPlatformProps();
 298 
 299     return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);
 300 }
 301 /*
 302  * Always detach the main thread so that it appears to have ended when
 303  * the application's main method exits.  This will invoke the
 304  * uncaught exception handler machinery if main threw an
 305  * exception.  An uncaught exception handler cannot change the
 306  * launcher's return code except by calling System.exit.
 307  *
 308  * Wait for all non-daemon threads to end, then destroy the VM.
 309  * This will actually create a trivial new Java waiter thread
 310  * named "DestroyJavaVM", but this will be seen as a different
 311  * thread from the one that executed main, even though they are
 312  * the same C thread.  This allows mainThread.join() and
 313  * mainThread.isAlive() to work as expected.
 314  */
 315 #define LEAVE() \
 316     do { \
 317         if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \
 318             JLI_ReportErrorMessage(JVM_ERROR2); \
 319             ret = 1; \
 320         } \
 321         if (JNI_TRUE) { \
 322             (*vm)->DestroyJavaVM(vm); \
 323             return ret; \
 324         } \
 325     } while (JNI_FALSE)
 326 
 327 #define CHECK_EXCEPTION_NULL_LEAVE(CENL_exception) \
 328     do { \
 329         if ((*env)->ExceptionOccurred(env)) { \
 330             JLI_ReportExceptionDescription(env); \
 331             LEAVE(); \
 332         } \
 333         if ((CENL_exception) == NULL) { \
 334             JLI_ReportErrorMessage(JNI_ERROR); \
 335             LEAVE(); \
 336         } \
 337     } while (JNI_FALSE)
 338 
 339 #define CHECK_EXCEPTION_LEAVE(CEL_return_value) \
 340     do { \
 341         if ((*env)->ExceptionOccurred(env)) { \
 342             JLI_ReportExceptionDescription(env); \
 343             ret = (CEL_return_value); \
 344             LEAVE(); \
 345         } \
 346     } while (JNI_FALSE)
 347 
 348 int JNICALL
 349 JavaMain(void * _args)
 350 {
 351     JavaMainArgs *args = (JavaMainArgs *)_args;
 352     int argc = args->argc;
 353     char **argv = args->argv;
 354     int mode = args->mode;
 355     char *what = args->what;
 356     InvocationFunctions ifn = args->ifn;
 357 
 358     JavaVM *vm = 0;
 359     JNIEnv *env = 0;
 360     jclass mainClass = NULL;
 361     jclass appClass = NULL; // actual application class being launched
 362     jmethodID mainID;
 363     jobjectArray mainArgs;
 364     int ret = 0;
 365     jlong start, end;
 366 


 428      *
 429      * Hence, future work should either:
 430      *     1)   Correct the local parsing code and verify that the
 431      *          Main-Class attribute gets properly passed through
 432      *          all environments,
 433      *     2)   Remove the vestages of maintaining main_class through
 434      *          the environment (and remove these comments).
 435      *
 436      * This method also correctly handles launching existing JavaFX
 437      * applications that may or may not have a Main-Class manifest entry.
 438      */
 439     mainClass = LoadMainClass(env, mode, what);
 440     CHECK_EXCEPTION_NULL_LEAVE(mainClass);
 441     /*
 442      * In some cases when launching an application that needs a helper, e.g., a
 443      * JavaFX application with no main method, the mainClass will not be the
 444      * applications own main class but rather a helper class. To keep things
 445      * consistent in the UI we need to track and report the application main class.
 446      */
 447     appClass = GetApplicationClass(env);
 448     NULL_CHECK_RETURN_VALUE(appClass, -1);
 449     /*
 450      * PostJVMInit uses the class name as the application name for GUI purposes,
 451      * for example, on OSX this sets the application name in the menu bar for
 452      * both SWT and JavaFX. So we'll pass the actual application class here
 453      * instead of mainClass as that may be a launcher or helper class instead
 454      * of the application class.
 455      */
 456     PostJVMInit(env, appClass, vm);
 457     /*
 458      * The LoadMainClass not only loads the main class, it will also ensure
 459      * that the main method's signature is correct, therefore further checking
 460      * is not required. The main method is invoked here so that extraneous java
 461      * stacks are not in the application stack trace.
 462      */
 463     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
 464                                        "([Ljava/lang/String;)V");
 465     CHECK_EXCEPTION_NULL_LEAVE(mainID);
 466 
 467     /* Build platform specific argument array */
 468     mainArgs = CreateApplicationArgs(env, argv, argc);