aboutsummaryrefslogtreecommitdiff
path: root/src/share/bin/java.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/bin/java.c')
-rw-r--r--src/share/bin/java.c218
1 files changed, 53 insertions, 165 deletions
diff --git a/src/share/bin/java.c b/src/share/bin/java.c
index 89ae857b1..0feafc1ed 100644
--- a/src/share/bin/java.c
+++ b/src/share/bin/java.c
@@ -102,8 +102,7 @@ static jboolean InitializeJVM(JavaVM **pvm, JNIEnv **penv,
InvocationFunctions *ifn);
static jstring NewPlatformString(JNIEnv *env, char *s);
static jobjectArray NewPlatformStringArray(JNIEnv *env, char **strv, int strc);
-static jclass LoadClass(JNIEnv *env, char *name);
-static jstring GetMainClassName(JNIEnv *env, char *jarname);
+static jclass LoadMainClass(JNIEnv *env, jboolean isJar, char *name);
static void TranslateApplicationArgs(int jargc, const char **jargv, int *pargc, char ***pargv);
static jboolean AddApplicationOptions(int cpathc, const char **cpathv);
@@ -301,6 +300,22 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
}
+#define CHECK_EXCEPTION_NULL_LEAVE(e) \
+ if ((*env)->ExceptionOccurred(env)) { \
+ JLI_ReportExceptionDescription(env); \
+ goto leave; \
+ } \
+ if ((e) == NULL) { \
+ JLI_ReportErrorMessage(JNI_ERROR); \
+ goto leave; \
+ }
+
+#define CHECK_EXCEPTION_LEAVE(rv) \
+ if ((*env)->ExceptionOccurred(env)) { \
+ JLI_ReportExceptionDescription(env); \
+ ret = (rv); \
+ goto leave; \
+ }
int JNICALL
JavaMain(void * _args)
@@ -321,9 +336,7 @@ JavaMain(void * _args)
int ret = 0;
jlong start, end;
-
/* Initialize the virtual machine */
-
start = CounterGet();
if (!InitializeJVM(&vm, &env, &ifn)) {
JLI_ReportErrorMessage(JVM_ERROR1);
@@ -332,11 +345,7 @@ JavaMain(void * _args)
if (printVersion || showVersion) {
PrintJavaVersion(env, showVersion);
- if ((*env)->ExceptionOccurred(env)) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- goto leave;
- }
+ CHECK_EXCEPTION_LEAVE(0);
if (printVersion) {
ret = 0;
goto leave;
@@ -346,11 +355,7 @@ JavaMain(void * _args)
/* If the user specified neither a class name nor a JAR file */
if (printXUsage || printUsage || (jarfile == 0 && classname == 0)) {
PrintUsage(env, printXUsage);
- if ((*env)->ExceptionOccurred(env)) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- ret=1;
- }
+ CHECK_EXCEPTION_LEAVE(1);
goto leave;
}
@@ -395,99 +400,25 @@ JavaMain(void * _args)
* the environment (and remove these comments).
*/
if (jarfile != 0) {
- mainClassName = GetMainClassName(env, jarfile);
- if ((*env)->ExceptionOccurred(env)) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- goto leave;
- }
- if (mainClassName == NULL) {
- JLI_ReportErrorMessage(JAR_ERROR1,jarfile, GEN_ERROR);
- goto leave;
- }
- classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
- if (classname == NULL) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- goto leave;
- }
- mainClass = LoadClass(env, classname);
- if(mainClass == NULL) { /* exception occured */
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(CLS_ERROR1, classname);
- goto leave;
- }
- (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
+ mainClass = LoadMainClass(env, JNI_TRUE, jarfile);
} else {
- mainClassName = NewPlatformString(env, classname);
- if (mainClassName == NULL) {
- JLI_ReportErrorMessage(CLS_ERROR2, classname, GEN_ERROR);
- goto leave;
- }
- classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
- if (classname == NULL) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- goto leave;
- }
- mainClass = LoadClass(env, classname);
- if(mainClass == NULL) { /* exception occured */
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(CLS_ERROR1, classname);
- goto leave;
- }
- (*env)->ReleaseStringUTFChars(env, mainClassName, classname);
+ mainClass = LoadMainClass(env, JNI_FALSE, classname);
}
+ CHECK_EXCEPTION_NULL_LEAVE(mainClass);
- /* Get the application's main method */
+ /*
+ * 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.
+ */
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
"([Ljava/lang/String;)V");
- if (mainID == NULL) {
- if ((*env)->ExceptionOccurred(env)) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- } else {
- JLI_ReportErrorMessage(CLS_ERROR3);
- }
- goto leave;
- }
-
- { /* Make sure the main method is public */
- jint mods;
- jmethodID mid;
- jobject obj = (*env)->ToReflectedMethod(env, mainClass,
- mainID, JNI_TRUE);
-
- if( obj == NULL) { /* exception occurred */
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- goto leave;
- }
-
- mid =
- (*env)->GetMethodID(env,
- (*env)->GetObjectClass(env, obj),
- "getModifiers", "()I");
- if ((*env)->ExceptionOccurred(env)) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- goto leave;
- }
-
- mods = (*env)->CallIntMethod(env, obj, mid);
- if ((mods & 1) == 0) { /* if (!Modifier.isPublic(mods)) ... */
- JLI_ReportErrorMessage(CLS_ERROR4);
- goto leave;
- }
- }
+ CHECK_EXCEPTION_NULL_LEAVE(mainID);
/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
- if (mainArgs == NULL) {
- JLI_ReportExceptionDescription(env);
- JLI_ReportErrorMessage(JNI_ERROR);
- goto leave;
- }
+ CHECK_EXCEPTION_NULL_LEAVE(mainArgs);
/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
@@ -498,8 +429,9 @@ JavaMain(void * _args)
*/
ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;
+leave:
/*
- * Detach the main thread so that it appears to have ended when
+ * Always detach the main thread so that it appears to have ended when
* the application's main method exits. This will invoke the
* uncaught exception handler machinery if main threw an
* exception. An uncaught exception handler cannot change the
@@ -508,10 +440,7 @@ JavaMain(void * _args)
if ((*vm)->DetachCurrentThread(vm) != 0) {
JLI_ReportErrorMessage(JVM_ERROR2);
ret = 1;
- goto leave;
}
-
- leave:
/*
* Wait for all non-daemon threads to end, then destroy the VM.
* This will actually create a trivial new Java waiter thread
@@ -525,7 +454,6 @@ JavaMain(void * _args)
return ret;
}
-
/*
* Checks the command line options to find which JVM type was
* specified. If no command line option was given for the JVM type,
@@ -1159,7 +1087,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
if (propname) {
jclass cls;
jmethodID mid;
- NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System"));
+ NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"getProperty",
@@ -1174,7 +1102,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
jclass cls;
jmethodID mid;
- NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset"));
+ NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls,
"isSupported",
@@ -1203,8 +1131,8 @@ NewPlatformString(JNIEnv *env, char *s)
jstring str = 0;
(*env)->SetByteArrayRegion(env, ary, 0, len, (jbyte *)s);
if (!(*env)->ExceptionOccurred(env)) {
+ NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
if (isEncodingSupported(env, enc) == JNI_TRUE) {
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([BLjava/lang/String;)V"));
str = (*env)->NewObject(env, cls, mid, ary, enc);
@@ -1215,7 +1143,6 @@ NewPlatformString(JNIEnv *env, char *s)
the encoding name, in which the StringCoding class will
pickup the iso-8859-1 as the fallback converter for us.
*/
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([B)V"));
str = (*env)->NewObject(env, cls, mid, ary);
@@ -1238,7 +1165,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
jarray ary;
int i;
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String"));
+ NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
for (i = 0; i < strc; i++) {
jstring str = NewPlatformString(env, *strv++);
@@ -1250,25 +1177,26 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
}
/*
- * Loads a class, convert the '.' to '/'.
+ * 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.
*/
static jclass
-LoadClass(JNIEnv *env, char *name)
+LoadMainClass(JNIEnv *env, jboolean isJar, char *name)
{
- char *buf = JLI_MemAlloc(JLI_StrLen(name) + 1);
- char *s = buf, *t = name, c;
jclass cls;
+ jmethodID mid;
+ jstring str;
+ jobject result;
jlong start, end;
- if (JLI_IsTraceLauncher())
+ if (JLI_IsTraceLauncher()) {
start = CounterGet();
-
- do {
- c = *t++;
- *s++ = (c == '.') ? '/' : c;
- } while (c != '\0');
- cls = (*env)->FindClass(env, buf);
- JLI_MemFree(buf);
+ }
+ NULL_CHECK0(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper"));
+ NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls, "checkAndLoadMain",
+ "(ZZLjava/lang/String;)Ljava/lang/Object;"));
+ str = (*env)->NewStringUTF(env, name);
+ result = (*env)->CallStaticObjectMethod(env, cls, mid, JNI_TRUE, isJar, str);
if (JLI_IsTraceLauncher()) {
end = CounterGet();
@@ -1277,49 +1205,9 @@ LoadClass(JNIEnv *env, char *name)
printf("----_JAVA_LAUNCHER_DEBUG----\n");
}
- return cls;
-}
-
-
-/*
- * Returns the main class name for the specified jar file.
- */
-static jstring
-GetMainClassName(JNIEnv *env, char *jarname)
-{
-#define MAIN_CLASS "Main-Class"
- jclass cls;
- jmethodID mid;
- jobject jar, man, attr;
- jstring str, result = 0;
-
- NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile"));
- NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
- "(Ljava/lang/String;)V"));
- NULL_CHECK0(str = NewPlatformString(env, jarname));
- NULL_CHECK0(jar = (*env)->NewObject(env, cls, mid, str));
- NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "getManifest",
- "()Ljava/util/jar/Manifest;"));
- man = (*env)->CallObjectMethod(env, jar, mid);
- if (man != 0) {
- NULL_CHECK0(mid = (*env)->GetMethodID(env,
- (*env)->GetObjectClass(env, man),
- "getMainAttributes",
- "()Ljava/util/jar/Attributes;"));
- attr = (*env)->CallObjectMethod(env, man, mid);
- if (attr != 0) {
- NULL_CHECK0(mid = (*env)->GetMethodID(env,
- (*env)->GetObjectClass(env, attr),
- "getValue",
- "(Ljava/lang/String;)Ljava/lang/String;"));
- NULL_CHECK0(str = NewPlatformString(env, MAIN_CLASS));
- result = (*env)->CallObjectMethod(env, attr, mid, str);
- }
- }
- return result;
+ return (jclass)result;
}
-
/*
* For tools, convert command line args thus:
* javac -cp foo:foo/"*" -J-ms32m ...
@@ -1522,7 +1410,7 @@ PrintJavaVersion(JNIEnv *env, jboolean extraLF)
jclass ver;
jmethodID print;
- NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version"));
+ NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
NULL_CHECK(print = (*env)->GetStaticMethodID(env,
ver,
(extraLF == JNI_TRUE) ? "println" : "print",
@@ -1534,7 +1422,7 @@ PrintJavaVersion(JNIEnv *env, jboolean extraLF)
}
/*
- * Prints default usage or the Xusage message, see sun.launcher.LauncherHelp.java
+ * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java
*/
static void
PrintUsage(JNIEnv* env, jboolean doXUsage)
@@ -1544,7 +1432,7 @@ PrintUsage(JNIEnv* env, jboolean doXUsage)
jstring jprogname, vm1, vm2;
int i;
- NULL_CHECK(cls = (*env)->FindClass(env, "sun/launcher/LauncherHelp"));
+ NULL_CHECK(cls = FindBootStrapClass(env, "sun/launcher/LauncherHelper"));
if (doXUsage) {