< prev index next >

src/java.base/share/native/libjli/java.c

Print this page

        

@@ -123,10 +123,12 @@
 
 static void PrintJavaVersion(JNIEnv *env, jboolean extraLF);
 static void PrintUsage(JNIEnv* env, jboolean doXUsage);
 static void ShowSettings(JNIEnv* env, char *optString);
 static void ListModules(JNIEnv* env, char *optString);
+static void SetNativeThreadName(JNIEnv* env, char *name);
+static void DispatchUncaughtException(JNIEnv* env, jthrowable throwable);
 
 static void SetPaths(int argc, char **argv);
 
 static void DumpState();
 static jboolean RemovableOption(char *option);

@@ -324,10 +326,23 @@
  * the same C thread.  This allows mainThread.join() and
  * mainThread.isAlive() to work as expected.
  */
 #define LEAVE() \
     do { \
+        jthrowable orig_throwable = (*env)->ExceptionOccurred(env); \
+        if (orig_throwable != NULL) { \
+            DispatchUncaughtException(env, orig_throwable); \
+            if ((*env)->ExceptionOccurred(env)) { \
+                JLI_ReportErrorMessage(EXCEPTION_ERROR); \
+                JLI_ReportExceptionDescription(env); \
+            } \
+        } \
+        SetNativeThreadName(env, "DestroyJavaVM"); \
+        if ((*env)->ExceptionOccurred(env)) { \
+            /* Clear non critical pending exceptions at this point. */ \
+            (*env)->ExceptionClear(env); \
+        } \
         if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \
             JLI_ReportErrorMessage(JVM_ERROR2); \
             ret = 1; \
         } \
         if (JNI_TRUE) { \

@@ -384,10 +399,16 @@
     if (!InitializeJVM(&vm, &env, &ifn)) {
         JLI_ReportErrorMessage(JVM_ERROR1);
         exit(1);
     }
 
+    SetNativeThreadName(env, "main");
+    if ((*env)->ExceptionOccurred(env)) {
+      /* Clear non critical pending exceptions at this point. */
+      (*env)->ExceptionClear(env);
+    }
+
     if (showSettings != NULL) {
         ShowSettings(env, showSettings);
         CHECK_EXCEPTION_LEAVE(1);
     }
 

@@ -1684,10 +1705,64 @@
     (*env)->CallStaticVoidMethod(env, cls, listModulesID,
                                  USE_STDERR,
                                  joptString);
 }
 
+/**
+ * Set native thread name if possible.
+ */
+static void
+SetNativeThreadName(JNIEnv *env, char *name)
+{
+    jmethodID currentThreadID, setNativeNameID;
+    jobject currentThread;
+    jstring nameString;
+    jclass cls;
+
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(cls = FindBootStrapClass(
+                                                      env, "java/lang/Thread"));
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(
+                       currentThreadID = (*env)->GetStaticMethodID(env, cls,
+                                      "currentThread", "()Ljava/lang/Thread;"));
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(
+                          currentThread = (*env)->CallStaticObjectMethod(
+                                                    env, cls, currentThreadID));
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(
+                          setNativeNameID = (*env)->GetMethodID(env, cls,
+                                    "setNativeName", "(Ljava/lang/String;Z)V"));
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(
+                                  nameString = (*env)->NewStringUTF(env, name));
+    (*env)->CallVoidMethod(env, currentThread, setNativeNameID,
+                           nameString, JNI_TRUE);
+}
+
+/**
+ * Dispatch uncaught exception in main thread.
+ */
+static void DispatchUncaughtException(JNIEnv* env, jthrowable throwable)
+{
+    jmethodID currentThreadID, dispatchUncaughtExceptionID;
+    jobject currentThread;
+    jclass cls;
+
+    (*env)->ExceptionClear(env);
+
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(cls = FindBootStrapClass(
+                                                      env, "java/lang/Thread"));
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(
+                       currentThreadID = (*env)->GetStaticMethodID(env, cls,
+                                      "currentThread", "()Ljava/lang/Thread;"));
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(
+                          currentThread = (*env)->CallStaticObjectMethod(
+                                                    env, cls, currentThreadID));
+    NULL_CHECK_WITHOUT_EXCEPTION_CHECK(
+              dispatchUncaughtExceptionID = (*env)->GetMethodID(env, cls,
+                      "dispatchUncaughtException", "(Ljava/lang/Throwable;)V"));
+    (*env)->CallVoidMethod(env, currentThread,
+                           dispatchUncaughtExceptionID, throwable);
+}
+
 /*
  * Prints default usage or the Xusage message, see sun.launcher.LauncherHelper.java
  */
 static void
 PrintUsage(JNIEnv* env, jboolean doXUsage)
< prev index next >