mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8315458: Implement JEP 463: Implicitly Declared Classes and Instance Main Method (Second Preview)
Reviewed-by: jlahoda, mcimadamore, vromero, rriggs, alanb, mchung
This commit is contained in:
parent
03759e892d
commit
04ad98ed32
48 changed files with 612 additions and 664 deletions
|
@ -387,6 +387,84 @@ JLI_Launch(int argc, char ** argv, /* main argc, argv */
|
|||
} \
|
||||
} while (JNI_FALSE)
|
||||
|
||||
#define CHECK_EXCEPTION_FAIL() \
|
||||
do { \
|
||||
if ((*env)->ExceptionOccurred(env)) { \
|
||||
(*env)->ExceptionClear(env); \
|
||||
return 0; \
|
||||
} \
|
||||
} while (JNI_FALSE)
|
||||
|
||||
|
||||
#define CHECK_EXCEPTION_NULL_FAIL(mainObject) \
|
||||
do { \
|
||||
if ((*env)->ExceptionOccurred(env)) { \
|
||||
(*env)->ExceptionClear(env); \
|
||||
return 0; \
|
||||
} else if (mainObject == NULL) { \
|
||||
return 0; \
|
||||
} \
|
||||
} while (JNI_FALSE)
|
||||
|
||||
/*
|
||||
* Invoke a static main with arguments. Returns 1 (true) if successful otherwise
|
||||
* processes the pending exception from GetStaticMethodID and returns 0 (false).
|
||||
*/
|
||||
int
|
||||
invokeStaticMainWithArgs(JNIEnv *env, jclass mainClass, jobjectArray mainArgs) {
|
||||
jmethodID mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
|
||||
"([Ljava/lang/String;)V");
|
||||
CHECK_EXCEPTION_FAIL();
|
||||
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke an instance main with arguments. Returns 1 (true) if successful otherwise
|
||||
* processes the pending exception from GetMethodID and returns 0 (false).
|
||||
*/
|
||||
int
|
||||
invokeInstanceMainWithArgs(JNIEnv *env, jclass mainClass, jobjectArray mainArgs) {
|
||||
jmethodID constructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
|
||||
CHECK_EXCEPTION_FAIL();
|
||||
jobject mainObject = (*env)->NewObject(env, mainClass, constructor);
|
||||
CHECK_EXCEPTION_NULL_FAIL(mainObject);
|
||||
jmethodID mainID = (*env)->GetMethodID(env, mainClass, "main",
|
||||
"([Ljava/lang/String;)V");
|
||||
CHECK_EXCEPTION_FAIL();
|
||||
(*env)->CallVoidMethod(env, mainObject, mainID, mainArgs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke a static main without arguments. Returns 1 (true) if successful otherwise
|
||||
* processes the pending exception from GetStaticMethodID and returns 0 (false).
|
||||
*/
|
||||
int
|
||||
invokeStaticMainWithoutArgs(JNIEnv *env, jclass mainClass) {
|
||||
jmethodID mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
|
||||
"()V");
|
||||
CHECK_EXCEPTION_FAIL();
|
||||
(*env)->CallStaticVoidMethod(env, mainClass, mainID);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invoke an instance main without arguments. Returns 1 (true) if successful otherwise
|
||||
* processes the pending exception from GetMethodID and returns 0 (false).
|
||||
*/
|
||||
int
|
||||
invokeInstanceMainWithoutArgs(JNIEnv *env, jclass mainClass) {
|
||||
jmethodID constructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
|
||||
CHECK_EXCEPTION_FAIL();
|
||||
jobject mainObject = (*env)->NewObject(env, mainClass, constructor);
|
||||
CHECK_EXCEPTION_NULL_FAIL(mainObject);
|
||||
jmethodID mainID = (*env)->GetMethodID(env, mainClass, "main",
|
||||
"()V");
|
||||
CHECK_EXCEPTION_FAIL();
|
||||
(*env)->CallVoidMethod(env, mainObject, mainID);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
JavaMain(void* _args)
|
||||
|
@ -403,9 +481,6 @@ JavaMain(void* _args)
|
|||
jclass mainClass = NULL;
|
||||
jclass appClass = NULL; // actual application class being launched
|
||||
jobjectArray mainArgs;
|
||||
jmethodID mainID;
|
||||
jmethodID constructor;
|
||||
jobject mainObject;
|
||||
int ret = 0;
|
||||
jlong start = 0, end = 0;
|
||||
|
||||
|
@ -491,9 +566,6 @@ JavaMain(void* _args)
|
|||
ret = 1;
|
||||
|
||||
/*
|
||||
* Get the application's main class. It also checks if the main
|
||||
* method exists.
|
||||
*
|
||||
* See bugid 5030265. The Main-Class name has already been parsed
|
||||
* from the manifest, but not parsed properly for UTF-8 support.
|
||||
* Hence the code here ignores the value previously extracted and
|
||||
|
@ -523,7 +595,7 @@ JavaMain(void* _args)
|
|||
* consistent in the UI we need to track and report the application main class.
|
||||
*/
|
||||
appClass = GetApplicationClass(env);
|
||||
NULL_CHECK_RETURN_VALUE(appClass, -1);
|
||||
CHECK_EXCEPTION_NULL_LEAVE(appClass);
|
||||
|
||||
/* Build platform specific argument array */
|
||||
mainArgs = CreateApplicationArgs(env, argv, argc);
|
||||
|
@ -545,59 +617,15 @@ JavaMain(void* _args)
|
|||
CHECK_EXCEPTION_LEAVE(1);
|
||||
|
||||
/*
|
||||
* The LoadMainClass not only loads the main class, it will also ensure
|
||||
* that the main method's signature is correct, therefore further checking
|
||||
* is not required. The main method is invoked here so that extraneous java
|
||||
* stacks are not in the application stack trace.
|
||||
* The main method is invoked here so that extraneous java stacks are not in
|
||||
* the application stack trace.
|
||||
*/
|
||||
#define MAIN_WITHOUT_ARGS 1
|
||||
#define MAIN_NONSTATIC 2
|
||||
|
||||
jclass helperClass = GetLauncherHelperClass(env);
|
||||
jmethodID getMainType = (*env)->GetStaticMethodID(env, helperClass,
|
||||
"getMainType",
|
||||
"()I");
|
||||
CHECK_EXCEPTION_NULL_LEAVE(getMainType);
|
||||
int mainType = (*env)->CallStaticIntMethod(env, helperClass, getMainType);
|
||||
CHECK_EXCEPTION_LEAVE(mainType);
|
||||
|
||||
switch (mainType) {
|
||||
case 0: {
|
||||
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
|
||||
"([Ljava/lang/String;)V");
|
||||
CHECK_EXCEPTION_NULL_LEAVE(mainID);
|
||||
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
|
||||
break;
|
||||
}
|
||||
case MAIN_WITHOUT_ARGS: {
|
||||
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
|
||||
"()V");
|
||||
CHECK_EXCEPTION_NULL_LEAVE(mainID);
|
||||
(*env)->CallStaticVoidMethod(env, mainClass, mainID);
|
||||
break;
|
||||
}
|
||||
case MAIN_NONSTATIC: {
|
||||
constructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
|
||||
CHECK_EXCEPTION_NULL_LEAVE(constructor);
|
||||
mainObject = (*env)->NewObject(env, mainClass, constructor);
|
||||
CHECK_EXCEPTION_NULL_LEAVE(mainObject);
|
||||
mainID = (*env)->GetMethodID(env, mainClass, "main",
|
||||
"([Ljava/lang/String;)V");
|
||||
CHECK_EXCEPTION_NULL_LEAVE(mainID);
|
||||
(*env)->CallVoidMethod(env, mainObject, mainID, mainArgs);
|
||||
break;
|
||||
}
|
||||
case MAIN_NONSTATIC | MAIN_WITHOUT_ARGS: {
|
||||
constructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
|
||||
CHECK_EXCEPTION_NULL_LEAVE(constructor);
|
||||
mainObject = (*env)->NewObject(env, mainClass, constructor);
|
||||
CHECK_EXCEPTION_NULL_LEAVE(mainObject);
|
||||
mainID = (*env)->GetMethodID(env, mainClass, "main",
|
||||
"()V");
|
||||
CHECK_EXCEPTION_NULL_LEAVE(mainID);
|
||||
(*env)->CallVoidMethod(env, mainObject, mainID);
|
||||
break;
|
||||
}
|
||||
if (!invokeStaticMainWithArgs(env, mainClass, mainArgs) &&
|
||||
!invokeInstanceMainWithArgs(env, mainClass, mainArgs) &&
|
||||
!invokeStaticMainWithoutArgs(env, mainClass) &&
|
||||
!invokeInstanceMainWithoutArgs(env, mainClass)) {
|
||||
ret = 1;
|
||||
LEAVE();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1593,8 +1621,9 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
|
|||
}
|
||||
|
||||
/*
|
||||
* Loads a class and verifies that the main class is present and it is ok to
|
||||
* call it for more details refer to the java implementation.
|
||||
* Calls LauncherHelper::checkAndLoadMain to verify that the main class
|
||||
* is present, it is ok to load the main class and then load the main class.
|
||||
* For more details refer to the java implementation.
|
||||
*/
|
||||
static jclass
|
||||
LoadMainClass(JNIEnv *env, int mode, char *name)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue