Я не уверен, что это то, что вы ищете, но есть обработчик для исключений, которые завершают потоки. Это обработчик для любого исключения, которое явно не перехватывается целью потока.
По умолчанию «обработчик необработанных исключений» просто вызывает printStackTrace()
на Throwable
, чтобы напечатать трассировку стека до System.err
. Однако вы можете заменить на свой UncaughtExceptionHandler
, который вместо этого регистрирует исключение в log4j:
class Log4jBackstop implements Thread.UncaughtExceptionHandler {
private static Logger log = Logger.getLogger(Log4jBackstop.class);
public void uncaughtException(Thread t, Throwable ex) {
log.error("Uncaught exception in thread: " + t.getName(), ex);
}
}
Если вы используете платформу executor, в которую передаете объект Runnable
, его потоки, вероятно, имеют свой собственный блок catch
, который предотвращает попадание исключений в обработчик необработанных исключений. Если вы хотите перехватить Runtime
исключений, один из способов сделать это - обернуть каждую задачу в оболочку регистрации, например:
class Log4jWrapper {
private final Logger log;
private final Runnable target;
Log4jWrapper(Logger log, Runnable target) {
this.log = Objects.requireNonNull(log);
this.target = Objects.requireNonNull(target);
}
public void run() {
try {
target.run();
} catch(RuntimeException ex) {
log.error("Uncaught exception.", ex);
throw ex;
}
}
}
...
Runnable realTask = ...;
executor.submit(new Log4jWrapper(Logger.getLogger(Whatever.class), realTask));