|
|
@ -36,7 +36,7 @@ class SilentExitExceptionHandler implements UncaughtExceptionHandler {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void uncaughtException(Thread thread, Throwable exception) {
|
|
|
|
public void uncaughtException(Thread thread, Throwable exception) {
|
|
|
|
if (exception instanceof SilentExitException) {
|
|
|
|
if (exception instanceof SilentExitException) {
|
|
|
|
if (jvmWillExit(thread)) {
|
|
|
|
if (isJvmExiting(thread)) {
|
|
|
|
preventNonZeroExitCode();
|
|
|
|
preventNonZeroExitCode();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -46,19 +46,7 @@ class SilentExitExceptionHandler implements UncaughtExceptionHandler {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void setup(Thread thread) {
|
|
|
|
private boolean isJvmExiting(Thread exceptionThread) {
|
|
|
|
UncaughtExceptionHandler handler = thread.getUncaughtExceptionHandler();
|
|
|
|
|
|
|
|
if (!(handler instanceof SilentExitExceptionHandler)) {
|
|
|
|
|
|
|
|
handler = new SilentExitExceptionHandler(handler);
|
|
|
|
|
|
|
|
thread.setUncaughtExceptionHandler(handler);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void exitCurrentThread() {
|
|
|
|
|
|
|
|
throw new SilentExitException();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean jvmWillExit(Thread exceptionThread) {
|
|
|
|
|
|
|
|
for (Thread thread : getAllThreads()) {
|
|
|
|
for (Thread thread : getAllThreads()) {
|
|
|
|
if (thread != exceptionThread && thread.isAlive() && !thread.isDaemon()) {
|
|
|
|
if (thread != exceptionThread && thread.isAlive() && !thread.isDaemon()) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
@ -67,22 +55,15 @@ class SilentExitExceptionHandler implements UncaughtExceptionHandler {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected void preventNonZeroExitCode() {
|
|
|
|
|
|
|
|
System.exit(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected Thread[] getAllThreads() {
|
|
|
|
protected Thread[] getAllThreads() {
|
|
|
|
ThreadGroup rootThreadGroup = getRootThreadGroup();
|
|
|
|
ThreadGroup rootThreadGroup = getRootThreadGroup();
|
|
|
|
int size = 32;
|
|
|
|
Thread[] threads = new Thread[32];
|
|
|
|
int threadCount;
|
|
|
|
int count = rootThreadGroup.enumerate(threads);
|
|
|
|
Thread[] threads;
|
|
|
|
while (count == threads.length) {
|
|
|
|
do {
|
|
|
|
threads = new Thread[threads.length * 2];
|
|
|
|
size *= 2;
|
|
|
|
count = rootThreadGroup.enumerate(threads);
|
|
|
|
threads = new Thread[size];
|
|
|
|
|
|
|
|
threadCount = rootThreadGroup.enumerate(threads);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (threadCount == threads.length);
|
|
|
|
return Arrays.copyOf(threads, count);
|
|
|
|
return Arrays.copyOf(threads, threadCount);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private ThreadGroup getRootThreadGroup() {
|
|
|
|
private ThreadGroup getRootThreadGroup() {
|
|
|
@ -93,6 +74,22 @@ class SilentExitExceptionHandler implements UncaughtExceptionHandler {
|
|
|
|
return candidate;
|
|
|
|
return candidate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected void preventNonZeroExitCode() {
|
|
|
|
|
|
|
|
System.exit(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void setup(Thread thread) {
|
|
|
|
|
|
|
|
UncaughtExceptionHandler handler = thread.getUncaughtExceptionHandler();
|
|
|
|
|
|
|
|
if (!(handler instanceof SilentExitExceptionHandler)) {
|
|
|
|
|
|
|
|
handler = new SilentExitExceptionHandler(handler);
|
|
|
|
|
|
|
|
thread.setUncaughtExceptionHandler(handler);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void exitCurrentThread() {
|
|
|
|
|
|
|
|
throw new SilentExitException();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static class SilentExitException extends RuntimeException {
|
|
|
|
private static class SilentExitException extends RuntimeException {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|