1 /* 2 * Copyright (c) 2014, 2019, 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 23 * questions. 24 */ 25 26 #include "JavaTypes.h" 27 #include "PlatformString.h" 28 29 #include <list> 30 31 32 #ifdef DEBUG 33 TString JavaException::CreateExceptionMessage(JNIEnv* Env, 34 jthrowable Exception, jmethodID GetCauseMethod, 35 jmethodID GetStackTraceMethod, jmethodID ThrowableToTStringMethod, 36 jmethodID FrameToTStringMethod) { 37 38 TString result; 39 jobjectArray frames = 40 (jobjectArray)Env->CallObjectMethod(Exception, GetStackTraceMethod); 41 42 // Append Throwable.toTString(). 43 if (0 != frames) { 44 jstring jstr = (jstring)Env->CallObjectMethod(Exception, 45 ThrowableToTStringMethod); 46 const char* str = Env->GetStringUTFChars(jstr, 0); 47 result += PlatformString(str).toPlatformString(); 48 Env->ReleaseStringUTFChars(jstr, str); 49 Env->DeleteLocalRef(jstr); 50 } 51 52 // Append stack trace if one exists. 53 if (Env->GetArrayLength(frames) > 0) { 54 jsize i = 0; 55 56 for (i = 0; i < Env->GetArrayLength(frames); i++) { 57 // Get the string from the next frame and append it to 58 // the error message. 59 jobject frame = Env->GetObjectArrayElement(frames, i); 60 jstring obj = (jstring)Env->CallObjectMethod(frame, 61 FrameToTStringMethod); 62 const char* str = Env->GetStringUTFChars(obj, 0); 63 result += _T("\n "); 64 result += PlatformString(str).toPlatformString(); 65 Env->ReleaseStringUTFChars(obj, str); 66 Env->DeleteLocalRef(obj); 67 Env->DeleteLocalRef(frame); 68 } 69 } 70 71 // If Exception has a cause then append the stack trace messages. 72 if (0 != frames) { 73 jthrowable cause = 74 (jthrowable)Env->CallObjectMethod(Exception, GetCauseMethod); 75 76 if (cause != NULL) { 77 result += CreateExceptionMessage(Env, cause, GetCauseMethod, 78 GetStackTraceMethod, ThrowableToTStringMethod, 79 FrameToTStringMethod); 80 } 81 } 82 83 return result; 84 } 85 #endif //DEBUG 86 87 JavaException::JavaException() : Exception() {} 88 89 //#ifdef WINDOWS 90 JavaException::JavaException(JNIEnv *Env, 91 const TString Message) : Exception(Message) { 92 //#endif //WINDOWS 93 //#ifdef POSIX 94 //JavaException::JavaException(JNIEnv *Env, TString message) { 95 //#endif //POSIX 96 97 FEnv = Env; 98 FException = Env->ExceptionOccurred(); 99 Env->ExceptionClear(); 100 101 #ifdef DEBUG 102 Platform& platform = Platform::GetInstance(); 103 104 if (platform.GetDebugState() == dsNone) { 105 jclass ThrowableClass = Env->FindClass("java/lang/Throwable"); 106 107 if (FEnv->ExceptionCheck() == JNI_TRUE) { 108 Env->ExceptionClear(); 109 return; 110 } 111 112 jmethodID GetCauseMethod = Env->GetMethodID(ThrowableClass, 113 "getCause", "()Ljava/lang/Throwable;"); 114 115 if (FEnv->ExceptionCheck() == JNI_TRUE) { 116 Env->ExceptionClear(); 117 return; 118 } 119 120 jmethodID GetStackTraceMethod = Env->GetMethodID(ThrowableClass, 121 "getStackTrace", "()[Ljava/lang/StackTraceElement;"); 122 123 if (FEnv->ExceptionCheck() == JNI_TRUE) { 124 Env->ExceptionClear(); 125 return; 126 } 127 128 jmethodID ThrowableToTStringMethod = Env->GetMethodID(ThrowableClass, 129 "toString", "()Ljava/lang/String;"); 130 131 if (FEnv->ExceptionCheck() == JNI_TRUE) { 132 Env->ExceptionClear(); 133 return; 134 } 135 136 jclass FrameClass = Env->FindClass("java/lang/StackTraceElement"); 137 138 if (FEnv->ExceptionCheck() == JNI_TRUE) { 139 Env->ExceptionClear(); 140 return; 141 } 142 143 jmethodID FrameToTStringMethod = Env->GetMethodID(FrameClass, 144 "toString", "()Ljava/lang/String;"); 145 146 if (FEnv->ExceptionCheck() == JNI_TRUE) { 147 Env->ExceptionClear(); 148 return; 149 } 150 151 TString lmessage = CreateExceptionMessage(Env, FException, 152 GetCauseMethod, GetStackTraceMethod, ThrowableToTStringMethod, 153 FrameToTStringMethod); 154 SetMessage(lmessage); 155 } 156 #endif //DEBUG 157 } 158 159 void JavaException::Rethrow() { 160 FEnv->Throw(FException); 161 }