• R/O
  • SSH
  • HTTPS

exewrap: Commit


Commit MetaInfo

Revision47 (tree)
Time2018-03-01 21:50:57
Authorhirukawa_ryo

Log Message

* exewrap 1.2.4
メインスレッドで例外が発生した場合、スタックトレースが正しく出力されないバグを修正しました。

Change Summary

Incremental Difference

--- exewrap/trunk/exewrap/src/Makefile (revision 46)
+++ exewrap/trunk/exewrap/src/Makefile (revision 47)
@@ -219,12 +219,9 @@
219219
220220 ### exewrap.util
221221
222-$(OBJ)\util.jar : $(OBJ) $(OBJ)\exewrap\util\EventLogHandler.class $(OBJ)\exewrap\util\EventLogStream.class $(OBJ)\exewrap\util\FileLogStream.class $(OBJ)\exewrap\util\UncaughtExceptionHandler.class $(OBJ)\exewrap\util\ConsoleOutputStream.class $(OBJ)\exewrap\util\Environment.class
222+$(OBJ)\util.jar : $(OBJ) $(OBJ)\exewrap\util\EventLogHandler.class $(OBJ)\exewrap\util\EventLogStream.class $(OBJ)\exewrap\util\FileLogStream.class $(OBJ)\exewrap\util\UncaughtExceptionHandler.class $(OBJ)\exewrap\util\Environment.class
223223 $(JAR) cvfM $(OBJ)\util.jar -C $(OBJ) exewrap\util
224224
225-$(OBJ)\exewrap\util\ConsoleOutputStream.class : $(OBJ) java\exewrap\util\ConsoleOutputStream.java
226- $(JAVAC) -Xlint:none -source 1.5 -target 1.5 -sourcepath java -d $(OBJ) java\exewrap\util\ConsoleOutputStream.java
227-
228225 $(OBJ)\exewrap\util\Environment.class : $(OBJ) java\exewrap\util\Environment.java
229226 $(JAVAC) -Xlint:none -source 1.5 -target 1.5 -sourcepath java -d $(OBJ) java\exewrap\util\Environment.java
230227
--- exewrap/trunk/exewrap/src/java/Loader.java (revision 46)
+++ exewrap/trunk/exewrap/src/java/Loader.java (revision 47)
@@ -78,9 +78,6 @@
7878 if(utilities.contains("EventLogHandler;")) {
7979 Class.forName("exewrap.util.EventLogHandler", true, systemClassLoader);
8080 }
81- if(utilities.contains("ConsoleOutputStream;")) {
82- Class.forName("exewrap.util.ConsoleOutputStream", true, systemClassLoader);
83- }
8481 }
8582
8683 if(mainClassName != null) {
--- exewrap/trunk/exewrap/src/java/exewrap/core/NativeMethods.java (revision 46)
+++ exewrap/trunk/exewrap/src/java/exewrap/core/NativeMethods.java (revision 47)
@@ -3,6 +3,6 @@
33 public class NativeMethods {
44 public static native void WriteConsole(byte[] b, int off, int len);
55 public static native void WriteEventLog(int type, String message);
6- public static native void UncaughtException(String thread, String message, String trace);
6+ public static native void UncaughtException(String thread, Throwable throwable);
77 public static native String SetEnvironment(String key, String value);
88 }
--- exewrap/trunk/exewrap/src/java/exewrap/util/ConsoleOutputStream.java (revision 46)
+++ exewrap/trunk/exewrap/src/java/exewrap/util/ConsoleOutputStream.java (revision 47)
@@ -1,32 +0,0 @@
1-package exewrap.util;
2-
3-import java.io.IOException;
4-import java.io.OutputStream;
5-import java.io.PrintStream;
6-
7-import exewrap.core.NativeMethods;
8-
9-public class ConsoleOutputStream extends OutputStream {
10- static {
11- System.setOut(new PrintStream(new ConsoleOutputStream()));
12- }
13-
14- @Override
15- public void write(int b) throws IOException {
16- NativeMethods.WriteConsole(new byte[] { (byte)(b & 0xFF) }, 0, 1);
17- }
18-
19- @Override
20- public void write(byte[] b) throws IOException {
21- if(b != null) {
22- NativeMethods.WriteConsole(b, 0, b.length);
23- }
24- }
25-
26- @Override
27- public void write(byte[] b, int off, int len) throws IOException {
28- if(b != null) {
29- NativeMethods.WriteConsole(b, off, len);
30- }
31- }
32-}
--- exewrap/trunk/exewrap/src/java/exewrap/util/UncaughtExceptionHandler.java (revision 46)
+++ exewrap/trunk/exewrap/src/java/exewrap/util/UncaughtExceptionHandler.java (revision 47)
@@ -1,8 +1,5 @@
11 package exewrap.util;
22
3-import java.io.PrintWriter;
4-import java.io.StringWriter;
5-
63 import exewrap.core.NativeMethods;
74
85 public class UncaughtExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler {
@@ -11,17 +8,7 @@
118 Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler());
129 }
1310
14- public void uncaughtException(Thread t, Throwable e) {
15- e.printStackTrace();
16- NativeMethods.UncaughtException(t.getName(), e.toString(), getStackTrace(e));
11+ public void uncaughtException(Thread thread, Throwable throwable) {
12+ NativeMethods.UncaughtException(thread.getName(), throwable);
1713 }
18-
19- private static String getStackTrace(Throwable t) {
20- StringWriter s = new StringWriter();
21- PrintWriter w = new PrintWriter(s);
22- t.printStackTrace(w);
23- w.flush();
24- s.flush();
25- return s.toString();
26- }
2714 }
--- exewrap/trunk/exewrap/src/image_service.c (revision 46)
+++ exewrap/trunk/exewrap/src/image_service.c (revision 47)
@@ -20,9 +20,8 @@
2020 #define SERVICE_START_BY_SCM 32
2121 #define SHOW_HELP_MESSAGE 64
2222
23-void OutputConsole(BYTE* buf, DWORD len);
24-void OutputMessage(const char* text);
25-UINT UncaughtException(const char* thread, const char* message, const char* trace);
23+void OutputMessage(const char* text);
24+UINT UncaughtException(const char* thread, const jthrowable throwable);
2625
2726 static int install_service(char* service_name, int argc, char* argv[], int opt_end);
2827 static int set_service_description(char* service_name, char* description);
@@ -187,15 +186,7 @@
187186 jthrowable throwable = (*env)->ExceptionOccurred(env);
188187 if (throwable != NULL)
189188 {
190- ToString(env, throwable, result.msg);
191- if (is_service)
192- {
193- WriteEventLog(EVENTLOG_ERROR_TYPE, result.msg);
194- }
195- else
196- {
197- OutputMessage(result.msg);
198- }
189+ UncaughtException("main", throwable);
199190 (*env)->DeleteLocalRef(env, throwable);
200191 }
201192 (*env)->ExceptionClear(env);
@@ -231,12 +222,6 @@
231222 return result.msg_id;
232223 }
233224
234-
235-void OutputConsole(BYTE* buf, DWORD len)
236-{
237-}
238-
239-
240225 void OutputMessage(const char* text)
241226 {
242227 DWORD written;
@@ -250,19 +235,162 @@
250235 WriteConsole(GetStdHandle(STD_ERROR_HANDLE), "\r\n", 2, &written, NULL);
251236 }
252237
253-
254-UINT UncaughtException(const char* thread, const char* message, const char* trace)
238+UINT UncaughtException(const char* thread, const jthrowable throwable)
255239 {
256240 BOOL is_service = (flags & SERVICE_START_BY_SCM);
241+
242+ jclass StringWriter = NULL;
243+ jmethodID StringWriter_init = NULL;
244+ jmethodID stringWriter_flush = NULL;
245+ jmethodID stringWriter_toString = NULL;
246+ jobject stringWriter = NULL;
247+ jclass PrintWriter = NULL;
248+ jmethodID PrintWriter_init = NULL;
249+ jmethodID printWriter_flush = NULL;
250+ jobject printWriter = NULL;
251+ jclass Throwable = NULL;
252+ jmethodID throwable_printStackTrace = NULL;
253+ jstring stacktrace = NULL;
254+ char* buf = NULL;
255+ char* sjis = NULL;
257256
257+ StringWriter = (*env)->FindClass(env, "java/io/StringWriter");
258+ if(StringWriter == NULL)
259+ {
260+ printf(_(MSG_ID_ERR_FIND_CLASS), "java.io.StringWriter");
261+ goto EXIT;
262+ }
263+ StringWriter_init = (*env)->GetMethodID(env, StringWriter, "<init>","()V");
264+ if(StringWriter_init == NULL)
265+ {
266+ printf(_(MSG_ID_ERR_GET_CONSTRUCTOR), "java.io.StringWriter()");
267+ goto EXIT;
268+ }
269+ stringWriter_flush = (*env)->GetMethodID(env, StringWriter, "flush", "()V");
270+ if(stringWriter_flush == NULL)
271+ {
272+ printf(_(MSG_ID_ERR_GET_METHOD), "java.io.StringWriter.flush()");
273+ goto EXIT;
274+ }
275+ stringWriter_toString = (*env)->GetMethodID(env, StringWriter, "toString", "()Ljava/lang/String;");
276+ if(stringWriter_toString == NULL)
277+ {
278+ printf(_(MSG_ID_ERR_GET_METHOD), "java.io.StringWriter.toString()");
279+ goto EXIT;
280+ }
281+ stringWriter = (*env)->NewObject(env, StringWriter, StringWriter_init);
282+ if(stringWriter == NULL)
283+ {
284+ printf(_(MSG_ID_ERR_NEW_OBJECT), "java.io.StringWriter()");
285+ goto EXIT;
286+ }
287+
288+ PrintWriter = (*env)->FindClass(env, "java/io/PrintWriter");
289+ if(PrintWriter == NULL)
290+ {
291+ printf(_(MSG_ID_ERR_FIND_CLASS), "java.io.PrintWriter");
292+ goto EXIT;
293+ }
294+ PrintWriter_init = (*env)->GetMethodID(env, PrintWriter, "<init>", "(Ljava/io/Writer;)V");
295+ if(PrintWriter_init == NULL)
296+ {
297+ printf(_(MSG_ID_ERR_GET_CONSTRUCTOR), "java.io.PrintWriter(java.io.Writer)");
298+ goto EXIT;
299+ }
300+ printWriter_flush = (*env)->GetMethodID(env, PrintWriter, "flush", "()V");
301+ if(printWriter_flush == NULL)
302+ {
303+ printf(_(MSG_ID_ERR_GET_METHOD), "java.io.PrintWriter.flush()");
304+ goto EXIT;
305+ }
306+ printWriter = (*env)->NewObject(env, PrintWriter, PrintWriter_init, stringWriter);
307+ if(printWriter == NULL)
308+ {
309+ printf(_(MSG_ID_ERR_NEW_OBJECT), "java.io.PrintWriter(java.io.Writer)");
310+ goto EXIT;
311+ }
312+
313+ Throwable = (*env)->FindClass(env, "java/lang/Throwable");
314+ if(Throwable == NULL)
315+ {
316+ printf(_(MSG_ID_ERR_FIND_CLASS), "java.lang.Throwable");
317+ goto EXIT;
318+ }
319+ throwable_printStackTrace = (*env)->GetMethodID(env, Throwable, "printStackTrace", "(Ljava/io/PrintWriter;)V");
320+ if(throwable_printStackTrace == NULL)
321+ {
322+ printf(_(MSG_ID_ERR_GET_METHOD), "java.lang.Throwable.printStackTrace(java.io.PrintWriter)");
323+ goto EXIT;
324+ }
325+
326+ buf = malloc(65536);
327+ if(buf == NULL)
328+ {
329+ goto EXIT;
330+ }
331+ strcpy(buf, "Exception in thread \"");
332+ strcat(buf, thread);
333+ strcat(buf, "\" ");
334+
335+ (*env)->CallObjectMethod(env, throwable, throwable_printStackTrace, printWriter);
336+ (*env)->CallObjectMethod(env, printWriter, printWriter_flush);
337+ (*env)->CallObjectMethod(env, stringWriter, stringWriter_flush);
338+ stacktrace = (jstring)(*env)->CallObjectMethod(env, stringWriter, stringWriter_toString);
339+ sjis = GetShiftJIS(env, stacktrace);
340+ strcat(buf, sjis);
341+
258342 if (is_service)
259343 {
260- char* buf = (char*)malloc(strlen(thread) + strlen(message) + strlen(trace) + 64);
344+ WriteEventLog(EVENTLOG_ERROR_TYPE, buf);
345+ }
346+ else
347+ {
348+ DWORD written;
349+ WriteConsole(GetStdHandle(STD_ERROR_HANDLE), buf, (DWORD)strlen(buf), &written, NULL);
350+ }
261351
262- sprintf(buf, "Exception in thread \"%s\" %s", thread, trace);
263- WriteEventLog(EVENTLOG_ERROR_TYPE, buf);
352+EXIT:
353+ if(sjis != NULL)
354+ {
355+ HeapFree(GetProcessHeap(), 0, sjis);
356+ sjis = NULL;
357+ }
358+ if(stacktrace != NULL)
359+ {
360+ (*env)->DeleteLocalRef(env, stacktrace);
361+ stacktrace = NULL;
362+ }
363+ if(buf != NULL)
364+ {
264365 free(buf);
366+ buf = NULL;
265367 }
368+ if(Throwable != NULL)
369+ {
370+ (*env)->DeleteLocalRef(env, Throwable);
371+ Throwable = NULL;
372+ }
373+ if(printWriter != NULL)
374+ {
375+ (*env)->DeleteLocalRef(env, printWriter);
376+ printWriter = NULL;
377+ }
378+ if(PrintWriter != NULL)
379+ {
380+ (*env)->DeleteLocalRef(env, PrintWriter);
381+ PrintWriter = NULL;
382+ }
383+ if(stringWriter != NULL)
384+ {
385+ (*env)->DeleteLocalRef(env, stringWriter);
386+ stringWriter = NULL;
387+ }
388+ if(StringWriter != NULL)
389+ {
390+ (*env)->DeleteLocalRef(env, StringWriter);
391+ StringWriter = NULL;
392+ }
393+
266394 return MSG_ID_ERR_UNCAUGHT_EXCEPTION;
267395 }
268396
@@ -818,16 +946,7 @@
818946 jthrowable throwable = (*env)->ExceptionOccurred(env);
819947 if (throwable != NULL)
820948 {
821- buf = malloc(2048);
822- ToString(env, throwable, buf);
823- if (is_service)
824- {
825- WriteEventLog(EVENTLOG_ERROR_TYPE, buf);
826- }
827- else
828- {
829- OutputMessage(buf);
830- }
949+ UncaughtException("scm", throwable);
831950 (*env)->DeleteLocalRef(env, throwable);
832951 }
833952 (*env)->ExceptionClear(env);
--- exewrap/trunk/exewrap/src/include/loader.h (revision 46)
+++ exewrap/trunk/exewrap/src/include/loader.h (revision 47)
@@ -8,7 +8,6 @@
88 #define UTIL_FILE_LOG_STREAM "FileLogStream;"
99 #define UTIL_EVENT_LOG_STREAM "EventLogStream;"
1010 #define UTIL_EVENT_LOG_HANDLER "EventLogHandler;"
11-#define UTIL_CONSOLE_OUTPUT_STREAM "ConsoleOutputStream;"
1211
1312 typedef struct _RESOURCE {
1413 BYTE* buf;
@@ -30,13 +29,12 @@
3029 extern BOOL LoadMainClass(int argc, char* argv[], char* utilities, LOAD_RESULT* result);
3130 extern BOOL SetSplashScreenResource(char* splash_screen_name, BYTE* splash_screen_image_buf, DWORD splash_screen_image_len);
3231 extern DWORD WINAPI RemoteCallMainMethod(void* _shared_memory_handle);
33-extern char* ToString(JNIEnv* env, jobject object, char* buf);
3432 extern char* GetModuleObjectName(const char* prefix);
3533 extern BYTE* GetResource(LPCTSTR name, RESOURCE* resource);
3634 extern char* GetWinErrorMessage(DWORD err, int* exit_code, char* buf);
3735 extern char* GetJniErrorMessage(int err, int* exit_code, char* buf);
3836 extern void JNICALL JNI_WriteEventLog(JNIEnv *env, jobject clazz, jint logType, jstring message);
39-extern void JNICALL JNI_UncaughtException(JNIEnv *env, jobject clazz, jstring thread, jstring message, jstring trace);
37+extern void JNICALL JNI_UncaughtException(JNIEnv *env, jobject clazz, jstring thread, jthrowable throwable);
4038 extern jstring JNICALL JNI_SetEnvironment(JNIEnv *env, jobject clazz, jstring key, jstring value);
4139
4240 #ifdef __cplusplus
--- exewrap/trunk/exewrap/src/image_console.c (revision 46)
+++ exewrap/trunk/exewrap/src/image_console.c (revision 47)
@@ -11,13 +11,9 @@
1111 #include "include/notify.h"
1212 #include "include/message.h"
1313
14-void OutputConsole(BYTE* buf, DWORD len);
15-void OutputMessage(const char* text);
16-UINT UncaughtException(const char* thread, const char* message, const char* trace);
14+void OutputMessage(const char* text);
15+UINT UncaughtException(const char* thread, const jthrowable throwable);
1716
18-static HANDLE hConOut = NULL;
19-
20-
2117 int main(int argc, char* argv[])
2218 {
2319 int err;
@@ -99,10 +95,18 @@
9995 synchronize_mutex_handle = NULL;
10096 }
10197 (*env)->CallStaticVoidMethod(env, result.MainClass, result.MainClass_main, result.MainClass_main_args);
98+
99+ if ((*env)->ExceptionCheck(env) == JNI_TRUE)
100+ {
101+ jthrowable throwable = (*env)->ExceptionOccurred(env);
102+ if (throwable != NULL)
103+ {
104+ UncaughtException("main", throwable);
105+ (*env)->DeleteLocalRef(env, throwable);
106+ }
107+ (*env)->ExceptionClear(env);
108+ }
102109
103- (*env)->ExceptionDescribe(env);
104- (*env)->ExceptionClear(env);
105-
106110 EXIT:
107111 if (synchronize_mutex_handle != NULL)
108112 {
@@ -127,25 +131,6 @@
127131 return result.msg_id;
128132 }
129133
130-void OutputConsole(BYTE* buf, DWORD len)
131-{
132- DWORD written;
133-
134- if (hConOut == INVALID_HANDLE_VALUE)
135- {
136- return;
137- }
138- if (hConOut == NULL)
139- {
140- hConOut = CreateFile("CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
141- if (hConOut == INVALID_HANDLE_VALUE)
142- {
143- return;
144- }
145- }
146- WriteConsole(hConOut, buf, len, &written, NULL);
147-}
148-
149134 void OutputMessage(const char* text)
150135 {
151136 DWORD written;
@@ -159,18 +144,52 @@
159144 WriteConsole(GetStdHandle(STD_ERROR_HANDLE), "\r\n", 2, &written, NULL);
160145 }
161146
162-UINT UncaughtException(const char* thread, const char* message, const char* trace)
147+UINT UncaughtException(const char* thread, const jthrowable throwable)
163148 {
164- if (thread != NULL)
149+ jclass Throwable = NULL;
150+ jmethodID throwable_printStackTrace = NULL;
151+ char* buf = NULL;
152+ DWORD written;
153+
154+ if(thread == NULL || throwable == NULL)
165155 {
166- char* buf = malloc(32 + strlen(thread));
167- sprintf(buf, "Exception in thread \"%s\"", thread);
168- OutputMessage(buf);
156+ goto EXIT;
157+ }
158+
159+ Throwable = (*env)->FindClass(env, "java/lang/Throwable");
160+ if(Throwable == NULL)
161+ {
162+ printf(_(MSG_ID_ERR_FIND_CLASS), "java.lang.Throwable");
163+ goto EXIT;
164+ }
165+ throwable_printStackTrace = (*env)->GetMethodID(env, Throwable, "printStackTrace", "()V");
166+ if(throwable_printStackTrace == NULL)
167+ {
168+ printf(_(MSG_ID_ERR_GET_METHOD), "java.lang.Throwable.printStackTrace()");
169+ goto EXIT;
170+ }
171+
172+ buf = malloc(1024);
173+ if(buf == NULL)
174+ {
175+ goto EXIT;
176+ }
177+ sprintf(buf, "Exception in thread \"%s\" ", thread);
178+ WriteConsole(GetStdHandle(STD_ERROR_HANDLE), buf, (DWORD)strlen(buf), &written, NULL);
179+
180+ (*env)->CallObjectMethod(env, throwable, throwable_printStackTrace);
181+
182+EXIT:
183+ if(buf != NULL)
184+ {
169185 free(buf);
186+ buf = NULL;
170187 }
171- if (trace != NULL)
188+ if(Throwable != NULL)
172189 {
173- OutputMessage(trace);
190+ (*env)->DeleteLocalRef(env, Throwable);
191+ Throwable = NULL;
174192 }
193+
175194 return MSG_ID_ERR_UNCAUGHT_EXCEPTION;
176195 }
--- exewrap/trunk/exewrap/src/loader.c (revision 46)
+++ exewrap/trunk/exewrap/src/loader.c (revision 47)
@@ -14,14 +14,12 @@
1414 BOOL LoadMainClass(int argc, char* argv[], char* utilities, LOAD_RESULT* result);
1515 BOOL SetSplashScreenResource(char* splash_screen_name, BYTE* splash_screen_image_buf, DWORD splash_screen_image_len);
1616 DWORD WINAPI RemoteCallMainMethod(void* _shared_memory_handle);
17-char* ToString(JNIEnv* env, jobject object, char* buf);
1817 char* GetModuleObjectName(const char* prefix);
1918 BYTE* GetResource(LPCTSTR name, RESOURCE* resource);
2019 char* GetWinErrorMessage(DWORD err, int* exit_code, char* buf);
2120 char* GetJniErrorMessage(int err, int* exit_code, char* buf);
22-void JNICALL JNI_WriteConsole(JNIEnv *env, jobject clazz, jbyteArray b, jint off, jint len);
2321 void JNICALL JNI_WriteEventLog(JNIEnv *env, jobject clazz, jint logType, jstring message);
24-void JNICALL JNI_UncaughtException(JNIEnv *env, jobject clazz, jstring thread, jstring message, jstring trace);
22+void JNICALL JNI_UncaughtException(JNIEnv *env, jobject clazz, jstring thread, jthrowable throwable);
2523 jstring JNICALL JNI_SetEnvironment(JNIEnv *env, jobject clazz, jstring key, jstring value);
2624
2725 static jint register_native(JNIEnv* env, jclass cls, const char* name, const char* signature, void* fnPtr);
@@ -28,9 +26,8 @@
2826 static void print_stack_trace(const char* text);
2927 static char** split_args(char* buffer, int* p_argc);
3028
31-extern void OutputConsole(BYTE* buf, DWORD len);
3229 extern void OutputMessage(const char* text);
33-extern UINT UncaughtException(const char* thread, const char* message, const char* trace);
30+extern UINT UncaughtException(const char* thread, const jthrowable throwable);
3431
3532 static jclass Loader = NULL;
3633 static jobject resources = NULL;
@@ -175,12 +172,6 @@
175172 sprintf(result->msg, _(MSG_ID_ERR_FIND_CLASS), "exewrap.core.NativeMethods");
176173 goto EXIT;
177174 }
178- if (register_native(env, NativeMethods, "WriteConsole", "([BII)V", JNI_WriteConsole) != 0)
179- {
180- result->msg_id = MSG_ID_ERR_REGISTER_NATIVE;
181- sprintf(result->msg, _(MSG_ID_ERR_REGISTER_NATIVE), "WriteConsole");
182- goto EXIT;
183- }
184175 if (register_native(env, NativeMethods, "WriteEventLog", "(ILjava/lang/String;)V", JNI_WriteEventLog) != 0)
185176 {
186177 result->msg_id = MSG_ID_ERR_REGISTER_NATIVE;
@@ -187,7 +178,7 @@
187178 sprintf(result->msg, _(MSG_ID_ERR_REGISTER_NATIVE), "WriteEventLog");
188179 goto EXIT;
189180 }
190- if (register_native(env, NativeMethods, "UncaughtException", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", JNI_UncaughtException) != 0)
181+ if (register_native(env, NativeMethods, "UncaughtException", "(Ljava/lang/String;Ljava/lang/Throwable;)V", JNI_UncaughtException) != 0)
191182 {
192183 result->msg_id = MSG_ID_ERR_REGISTER_NATIVE;
193184 sprintf(result->msg, _(MSG_ID_ERR_REGISTER_NATIVE), "UncaughtException");
@@ -553,7 +544,13 @@
553544 (*env)->CallStaticVoidMethod(env, MainClass, MainClass_main, args);
554545 if ((*env)->ExceptionCheck(env) == JNI_TRUE)
555546 {
556- print_stack_trace(NULL);
547+ jthrowable throwable = (*env)->ExceptionOccurred(env);
548+ if (throwable != NULL)
549+ {
550+ UncaughtException("main", throwable);
551+ (*env)->DeleteLocalRef(env, throwable);
552+ }
553+ (*env)->ExceptionClear(env);
557554 }
558555 DetachJavaVM();
559556
@@ -567,57 +564,7 @@
567564 }
568565
569566
570-char* ToString(JNIEnv* env, jobject object, char* buf)
571-{
572- jclass Object;
573- jmethodID Object_getClass;
574- jclass object_class;
575- jmethodID object_class_toString;
576- jstring str;
577- char* sjis;
578567
579- if (object == NULL)
580- {
581- return NULL;
582- }
583- Object = (*env)->FindClass(env, "java/lang/Object");
584- if (Object == NULL)
585- {
586- return NULL;
587- }
588- Object_getClass = (*env)->GetMethodID(env, Object, "getClass", "()Ljava/lang/Class;");
589- if (Object_getClass == NULL)
590- {
591- return NULL;
592- }
593- object_class = (*env)->CallObjectMethod(env, object, Object_getClass);
594- if (object_class == NULL)
595- {
596- return NULL;
597- }
598- object_class_toString = (*env)->GetMethodID(env, object_class, "toString", "()Ljava/lang/String;");
599- if (object_class_toString == NULL)
600- {
601- return NULL;
602- }
603- str = (*env)->CallObjectMethod(env, object, object_class_toString);
604- if (str == NULL)
605- {
606- return NULL;
607- }
608-
609- sjis = GetShiftJIS(env, str);
610- if (buf != NULL)
611- {
612- strcpy(buf, sjis);
613- HeapFree(GetProcessHeap(), 0, sjis);
614- sjis = buf;
615- }
616-
617- return sjis;
618-}
619-
620-
621568 char* GetModuleObjectName(const char* prefix)
622569 {
623570 char* object_name = (char*)HeapAlloc(GetProcessHeap(), 0, MAX_PATH + 32);
@@ -636,7 +583,6 @@
636583 return object_name;
637584 }
638585
639-
640586 BYTE* GetResource(LPCTSTR name, RESOURCE* resource)
641587 {
642588 HRSRC hrsrc;
@@ -721,17 +667,6 @@
721667 }
722668
723669
724-void JNICALL JNI_WriteConsole(JNIEnv *env, jobject clazz, jbyteArray b, jint off, jint len)
725-{
726- jboolean isCopy;
727- BYTE* buf;
728-
729- buf = (*env)->GetByteArrayElements(env, b, &isCopy);
730- OutputConsole(buf, len);
731- (*env)->ReleaseByteArrayElements(env, b, buf, 0);
732-}
733-
734-
735670 void JNICALL JNI_WriteEventLog(JNIEnv *env, jobject clazz, jint logType, jstring message)
736671 {
737672 WORD nType;
@@ -750,31 +685,19 @@
750685 }
751686
752687
753-void JNICALL JNI_UncaughtException(JNIEnv *env, jobject clazz, jstring thread, jstring message, jstring trace)
688+void JNICALL JNI_UncaughtException(JNIEnv *env, jobject clazz, jstring thread, jthrowable throwable)
754689 {
755690 char* sjis_thread;
756- char* sjis_message;
757- char* sjis_trace;
758691 UINT exit_code;
759692
760693 sjis_thread = GetShiftJIS(env, thread);
761- sjis_message = GetShiftJIS(env, message);
762- sjis_trace = GetShiftJIS(env, trace);
763694
764- exit_code = UncaughtException(sjis_thread, sjis_message, sjis_trace);
695+ exit_code = UncaughtException(sjis_thread, throwable);
765696
766697 if (sjis_thread != NULL)
767698 {
768699 HeapFree(GetProcessHeap(), 0, sjis_thread);
769700 }
770- if (sjis_message != NULL)
771- {
772- HeapFree(GetProcessHeap(), 0, sjis_message);
773- }
774- if (sjis_trace != NULL)
775- {
776- HeapFree(GetProcessHeap(), 0, sjis_trace);
777- }
778701
779702 ExitProcess(exit_code);
780703 }
--- exewrap/trunk/exewrap/src/exewrap.c (revision 46)
+++ exewrap/trunk/exewrap/src/exewrap.c (revision 47)
@@ -18,9 +18,8 @@
1818 #define DEFAULT_VERSION "0.0"
1919 #define DEFAULT_PRODUCT_VERSION "0.0"
2020
21-void OutputConsole(BYTE* buf, DWORD len);
22-void OutputMessage(const char* text);
23-UINT UncaughtException(const char* thread, const char* message, const char* trace);
21+void OutputMessage(const char* text);
22+UINT UncaughtException(const char* thread, const jthrowable throwable);
2423
2524 static char** parse_opt(int argc, char* argv[]);
2625 static DWORD get_version_revision(char* filename);
@@ -719,8 +718,6 @@
719718 HANDLE hFile;
720719 BYTE* buf = NULL;
721720 DWORD write_size;
722- char* dir;
723- char* ptr;
724721
725722 hFile = CreateFile(filename, FILE_APPEND_DATA, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
726723 if (hFile == INVALID_HANDLE_VALUE)
@@ -1204,17 +1201,12 @@
12041201 }
12051202
12061203
1207-void OutputConsole(BYTE* buf, DWORD len)
1208-{
1209-}
1210-
1211-
12121204 void OutputMessage(const char* text)
12131205 {
12141206 }
12151207
12161208
1217-UINT UncaughtException(const char* thread, const char* message, const char* trace)
1209+UINT UncaughtException(const char* thread, const jthrowable throwable)
12181210 {
12191211 return 0;
12201212 }
--- exewrap/trunk/exewrap/src/image_gui.c (revision 46)
+++ exewrap/trunk/exewrap/src/image_gui.c (revision 47)
@@ -21,9 +21,8 @@
2121 #include "include/notify.h"
2222 #include "include/message.h"
2323
24-void OutputConsole(BYTE* buf, DWORD len);
2524 void OutputMessage(const char* text);
26-UINT UncaughtException(const char* thread, const char* message, const char* trace);
25+UINT UncaughtException(const char* thread, const jthrowable throwable);
2726
2827 static char** get_args(int* argc);
2928 static char* _w2a(LPCWSTR s);
@@ -164,12 +163,11 @@
164163 jthrowable throwable = (*env)->ExceptionOccurred(env);
165164 if (throwable != NULL)
166165 {
167- ToString(env, throwable, result.msg);
168- OutputMessage(result.msg);
166+ UncaughtException("main", throwable);
169167 (*env)->DeleteLocalRef(env, throwable);
170168 }
169+ (*env)->ExceptionClear(env);
171170 }
172- (*env)->ExceptionClear(env);
173171
174172 EXIT:
175173 if (synchronize_mutex_handle != NULL)
@@ -195,12 +193,6 @@
195193 return result.msg_id;
196194 }
197195
198-
199-void OutputConsole(BYTE* buf, DWORD len)
200-{
201-}
202-
203-
204196 void OutputMessage(const char* text)
205197 {
206198 char buffer[MAX_PATH];
@@ -217,19 +209,150 @@
217209 MessageBox(NULL, text, filename, MB_ICONEXCLAMATION | MB_APPLMODAL | MB_OK | MB_SETFOREGROUND);
218210 }
219211
212+UINT UncaughtException(const char* thread, const jthrowable throwable)
213+{
214+ jclass System = NULL;
215+ jfieldID System_err = NULL;
216+ jobject printStream = NULL;
217+ jclass PrintStream = NULL;
218+ jmethodID printStream_print = NULL;
219+ jmethodID printStream_flush = NULL;
220+ jclass Throwable = NULL;
221+ jmethodID throwable_printStackTrace = NULL;
222+ jmethodID throwable_getMessage = NULL;
223+ jstring leading = NULL;
224+ jstring message = NULL;
225+ char* buf = NULL;
226+ char* sjis = NULL;
220227
221-UINT UncaughtException(const char* thread, const char* message, const char* trace)
222-{
223- //for message box
224- char* buf = (char*)malloc(strlen(thread) + strlen(message) + 64);
225- sprintf(buf, "Exception in thread \"%s\"\r\n%s", thread, message);
228+ if(thread == NULL || throwable == NULL)
229+ {
230+ goto EXIT;
231+ }
232+
233+ System = (*env)->FindClass(env, "java/lang/System");
234+ if(System == NULL)
235+ {
236+ printf(_(MSG_ID_ERR_FIND_CLASS), "java.lang.System");
237+ goto EXIT;
238+ }
239+ System_err = (*env)->GetStaticFieldID(env, System, "err", "Ljava/io/PrintStream;");
240+ if(System_err == NULL)
241+ {
242+ printf(_(MSG_ID_ERR_GET_FIELD), "java.lang.System.err");
243+ goto EXIT;
244+ }
245+ printStream = (*env)->GetStaticObjectField(env, System, System_err);
246+ if(printStream == NULL)
247+ {
248+ printf(_(MSG_ID_ERR_GET_FIELD), "java.lang.System.err");
249+ goto EXIT;
250+ }
251+ PrintStream = (*env)->FindClass(env, "java/io/PrintStream");
252+ if(PrintStream == NULL)
253+ {
254+ printf(_(MSG_ID_ERR_FIND_CLASS), "java.io.PrintStream");
255+ goto EXIT;
256+ }
257+ printStream_print = (*env)->GetMethodID(env, PrintStream, "print", "(Ljava/lang/String;)V");
258+ if(printStream_print == NULL)
259+ {
260+ printf(_(MSG_ID_ERR_GET_METHOD), "java.io.PrintStream.print(String)");
261+ goto EXIT;
262+ }
263+ printStream_flush = (*env)->GetMethodID(env, PrintStream, "flush", "()V");
264+ if(printStream_flush == NULL)
265+ {
266+ printf(_(MSG_ID_ERR_GET_METHOD), "java.io.PrintStream.flush()");
267+ goto EXIT;
268+ }
269+ Throwable = (*env)->FindClass(env, "java/lang/Throwable");
270+ if(Throwable == NULL)
271+ {
272+ printf(_(MSG_ID_ERR_FIND_CLASS), "java.lang.Throwable");
273+ goto EXIT;
274+ }
275+ throwable_printStackTrace = (*env)->GetMethodID(env, Throwable, "printStackTrace", "()V");
276+ if(throwable_printStackTrace == NULL)
277+ {
278+ printf(_(MSG_ID_ERR_GET_METHOD), "java.lang.Throwable.printStackTrace()");
279+ goto EXIT;
280+ }
281+ throwable_getMessage = (*env)->GetMethodID(env, Throwable, "getMessage", "()Ljava/lang/String;");
282+ if(throwable_getMessage == NULL)
283+ {
284+ printf(_(MSG_ID_ERR_GET_METHOD), "java.lang.Throwable.getMessage()");
285+ goto EXIT;
286+ }
287+
288+ buf = malloc(1024);
289+ if(buf == NULL)
290+ {
291+ goto EXIT;
292+ }
293+ strcpy(buf, "Exception in thread \"");
294+ strcat(buf, thread);
295+ strcat(buf, "\" ");
296+ leading = GetJString(env, buf);
297+
298+ (*env)->CallObjectMethod(env, printStream, printStream_print, leading);
299+ (*env)->CallObjectMethod(env, throwable, throwable_printStackTrace);
300+ (*env)->CallObjectMethod(env, printStream, printStream_flush);
301+
302+ message = (*env)->CallObjectMethod(env, throwable, throwable_getMessage);
303+ if(message == NULL)
304+ {
305+ goto EXIT;
306+ }
307+ sjis = GetShiftJIS(env, message);
308+ sprintf(buf, "Exception in thread \"%s\"\r\n%s", thread, sjis);
226309 OutputMessage(buf);
227- free(buf);
310+
311+EXIT:
312+ if(sjis != NULL)
313+ {
314+ HeapFree(GetProcessHeap(), 0, sjis);
315+ sjis = NULL;
316+ }
317+ if(message != NULL)
318+ {
319+ (*env)->DeleteLocalRef(env, message);
320+ message = NULL;
321+ }
322+ if(buf != NULL)
323+ {
324+ free(buf);
325+ buf = NULL;
326+ }
327+ if(leading != NULL)
328+ {
329+ (*env)->DeleteLocalRef(env, leading);
330+ leading = NULL;
331+ }
332+ if(Throwable != NULL)
333+ {
334+ (*env)->DeleteLocalRef(env, Throwable);
335+ Throwable = NULL;
336+ }
337+ if(PrintStream != NULL)
338+ {
339+ (*env)->DeleteLocalRef(env, PrintStream);
340+ PrintStream = NULL;
341+ }
342+ if(printStream != NULL)
343+ {
344+ (*env)->DeleteLocalRef(env, printStream);
345+ printStream = NULL;
346+ }
347+ if(System != NULL)
348+ {
349+ (*env)->DeleteLocalRef(env, System);
350+ System = NULL;
351+ }
228352
229353 return MSG_ID_ERR_UNCAUGHT_EXCEPTION;
230354 }
231355
232-
233356 static char** get_args(int* argc)
234357 {
235358 LPWSTR lpCmdLineW;
Show on old repository browser