/*
* Entry point.
*/
int
JLI_Launch(int argc, char ** argv, /* main argc, argc */
int jargc, const char** jargv, /* java args */
int appclassc, const char** appclassv, /* app classpath */
const char* fullversion, /* full version defined */
const char* dotversion, /* dot version defined */
const char* pname, /* program name */
const char* lname, /* launcher name */
jboolean javaargs, /* JAVA_ARGS */
jboolean cpwildcard, /* classpath wildcard*/
jboolean javaw, /* windows-only javaw */
jint ergo /* ergonomics class policy */
)
{
int mode = LM_UNKNOWN;
char *what = NULL;
char *cpath = 0;
char *main_class = NULL;
int ret;
InvocationFunctions ifn;
jlong start, end;
char jvmpath[MAXPATHLEN];
char jrepath[MAXPATHLEN];
char jvmcfg[MAXPATHLEN];
_fVersion = fullversion;
_dVersion = dotversion;
_launcher_name = lname;
_program_name = pname;
_is_java_args = javaargs;
_wc_enabled = cpwildcard;
_ergo_policy = ergo;
//1.如果javaw==true,初始化MFC窗体
//2.根据环境变量_JAVA_LAUNCHER_DEBUG的取值决定是否输出JVM Trace信息
// - 如果_JAVA_LAUNCHER_DEBUG==1,输出JVM Trace信息
InitLauncher(javaw);
//打印Launcher状态信息
DumpState();
//JVM Trace打印命令行参数
if (JLI_IsTraceLauncher()) {
int i;
/**
* Command line args:
* argv[0] = java
* argv[1] = -jar
* argv[2] = test.jar
* /
printf("Command line args:\n");
for (i = 0; i < argc ; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
AddOption("-Dsun.java.launcher.diag=true", NULL);
}
/*
* Make sure the specified version of the JRE is running.
*
* There are three things to note about the SelectVersion() routine:
* 1) If the version running isn't correct, this routine doesn't
* return (either the correct version has been exec'd or an error
* was issued).
* 2) Argc and Argv in this scope are *not* altered by this routine.
* It is the responsibility of subsequent code to ignore the
* arguments handled by this routine.
* 3) As a side-effect, the variable "main_class" is guaranteed to
* be set (if it should ever be set). This isn't exactly the
* poster child for structured programming, but it is a small
* price to pay for not processing a jar file operand twice.
* (Note: This side effect has been disabled. See comment on
* bugid 5030265 below.)
*/
//加载Manifest判断JRE Version是否有效
SelectVersion(argc, argv, &main_class);
CreateExecutionEnvironment(&argc, &argv,
jrepath, sizeof(jrepath),
jvmpath, sizeof(jvmpath),
jvmcfg, sizeof(jvmcfg));
if (!IsJavaArgs()) {
//根据是否配置命令行参数:-XX:NativeMemoryTracking=
//决定是否设置环境变量:NMT_LEVEL_${PID}=value,用以内存跟踪
SetJvmEnvironment(argc,argv);
}
ifn.CreateJavaVM = 0;
ifn.GetDefaultJavaVMInitArgs = 0;
if (JLI_IsTraceLauncher()) {
start = CounterGet();
}
//1. 加载Microsoft C Runtime Library:%JRE_HOME%\\bin\\${jvmtype}\\jvm.dll
//2. 加载jvm:%JRE_HOME%\\bin\\${jvmtype}\\jvm.dll
if (!LoadJavaVM(jvmpath, &ifn)) {
return(6);
}
if (JLI_IsTraceLauncher()) {
end = CounterGet();
}
//39449 micro seconds to LoadJavaVM
JLI_TraceLauncher("%ld micro seconds to LoadJavaVM\n",
(long)(jint)Counter2Micros(end-start));
//移除命令行第一条命令:
//argv[0] = C:\Tools\Java\open-jre1.8.0_202\bin\java.exe
++argv;
--argc;
if (IsJavaArgs()) {
/* Preprocess wrapper arguments */
//优化-J开头的命令行参数 && 展开-cp | -classpath配置项通配符
TranslateApplicationArgs(jargc, jargv, &argc, &argv);
//添加可选参数:
//1. -Denv.class.path= -> CLASSPATH
//2. -Dapplication.home= -> APP_HOME
//3. -Djava.class.path= -> 取决于:宏定义变量JAVA_ARGS是否存在
if (!AddApplicationOptions(appclassc, appclassv)) {
return(1);
}
} else {
/* Set default CLASSPATH */
//如果环境变量:CLASSPATH 未定义,默认设置为当前目录:"."
cpath = getenv("CLASSPATH");
if (cpath == NULL) {
cpath = ".";
}
//添加可选参数:-Djava.class.path=当前目录下的所有jar文件路径
SetClassPath(cpath);
}
/* Parse command line options; if the return value of
* ParseArguments is false, the program should exit.
*/
//剥离以'-'开头的参数并设置相应的jvm可选参数
//mode:LM_UNKNOWN | LM_CLASSPATH | LM_JAR
//what:
//1. 如果是jar包启动,what值为jar包路径:test.jar | D:\workdir\study\out\artifacts\test\test.jar
//2. 如果是Class启动,what值为class完整名:com.johnjoe.study.Test
if (!ParseArguments(&argc, &argv, &mode, &what, &ret, jrepath))
{
return(ret);
}
/* Override class path if -jar flag was specified */
//jar包启动
if (mode == LM_JAR) {
//重置可选参数:-Djava.class.path=
SetClassPath(what); /* Override class path */
}
/* set the -Dsun.java.command pseudo property */
//添加可选参数:-Dsun.java.command=${java.exe完整路径} [ ${主程序完整名} | ${jar包}] ${命令行参数}
SetJavaCommandLineProp(what, argc, argv);
/* Set the -Dsun.java.launcher pseudo property */
//添加可选参数:-Dsun.java.launcher=SUN_STANDARD
SetJavaLauncherProp();
/* set the -Dsun.java.launcher.* platform properties */
//(**Linux only**)添加可选参数:-Dsun.java.launcher.pid=
SetJavaLauncherPlatformProps();
return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret);
}