Открытый Java-обработчик исключений Java
У меня есть приложение и нужно закодировать собственный глобальный обработчик исключенных исключений. Я прочитал все потоки stackoverflow, и каждый из них просто отсутствует ясный и простой пример того, как это должно быть реализовано.
Рассмотрим следующий простой пример:
public static void log(String msg) throws Exception {
String logPath = "/application/logs/java.log";
Calendar c = new GregorianCalendar();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String now = format.format(c.getTime());
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logPath, true)));
out.println(now + " " + msg);
out.close();
}
Он выдает стандартное исключение, которое является стандартным выходом. Как реализовать собственное исключение, которое переопределяет стандартное, чем-то простым, как вывод ошибки в файл журнала? Очевидно, что фактическое приложение намного больше, и мы говорим о неперехваченных исключениях, поэтому блоки try/catch не являются опцией.
ОБНОВЛЕНИЕ:. Если бы вы могли ответить на этот вопрос с очень ясным полным примером, потому что я нашел десятки примеров, подобных тому, который был предоставлен одним из них @RamonBoza, но я понятия не имею, как их реализовать, что этот вопрос есть.
UPDATE2: Поэтому я попытался проверить единственный пример в ответе ниже, он явно не работает. Я создал новый файл класса "MyRunnable" и вставил в него код:
package mypackage;
Thread t = new Thread(new MyRunnable());
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
});
t.start();
//outside that class
class MyRunnable implements Runnable(){
public void run(){
throw new RuntimeException("hey you!");
}
}
Излишне говорить, что я получаю кучу ошибок с этим. Как может быть что-то вне класса в любом случае?
UPDATE3: Это решение, которое в конечном итоге работает:
package mypackage;
public class MyClass {
public static void main(String[] args) throws Exception {
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String stacktrace = sw.toString();
System.out.println(stacktrace);
}
});
//main method code
}
//Rest of the methods here
}
Ответы
Ответ 1
Вы можете установить UncaughtExceptionHandler для потока, управляющего указанным выше кодом:
// t is the parent code thread
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
});
Java-документы для UncaughtExceptionHandler -
Когда поток вот-вот завершится из-за неперехваченного исключения, Виртуальная машина Java запросит поток для своего UncaughtExceptionHandler с использованием Thread.getUncaughtExceptionHandler() и вызовет метод обработчика uncaughtException, передав поток и исключение в качестве аргументов
setUncaughtExceptionHandler обычно используется для освобождения памяти или уничтожения потоков, которые система не сможет убить и, возможно, останется зомби.
Реальный пример:
Thread t = new Thread(new MyRunnable());
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
});
t.start();
//outside that class
class MyRunnable implements Runnable(){
public void run(){
throw new RuntimeException("hey you!");
}
}
Ответ 2
Вы можете использовать UncaughtExceptionHandler для обработки исключения, из-за чего поток прерывается.
Java-документ для UncaughtExceptionHandler -
Интерфейс для обработчиков, вызываемых, когда поток прерывается к невостребованному исключению. Когда поток вот-вот завершится из-за неперехваченного исключения, виртуальная машина Java запросит поток для своего UncaughtExceptionHandler, используя Thread.getUncaughtExceptionHandler(), и вызовет метод обработчика uncaughtException, передав поток и исключение в качестве аргументов
Вам необходимо реализовать этот интерфейс и настроить реализацию UncaughtExceptionHandler для потока с помощью метода setUncaughtExceptionHandler.
Есть два способа сделать это:
- setUncaughtExceptionHandler
- setDefaultUncaughtExceptionHandler
1) setUncaughtExceptionHandler - это будет обработчик исключений, специфичный для потока. Поэтому в случае, если этот поток будет прерван каким-то необработанным исключением, этот обработчик будет использоваться.
2) setDefaultUncaughtExceptionHandler - это будет обработчик исключений по умолчанию в случае, если для потока нет конкретного обработчика исключенных исключений.
Пример -
class MyExceptionHandler implements UncaughtExceptionHandler{
@Override
public void uncaughtException(Thread arg0, Throwable arg1) {
System.out.println("[DEFAULT EXCEPTION HANDLER] Caught some exception");
}
}
class MyThread extends Thread{
public MyThread() {
setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("[THREAD SPECIFIC] My exception handler");
}
});
}
public void run(){
throw new RuntimeException();
}
}
public class Test {
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
new MyThread().start();
// current thread does not have a thread specific exception handler
throw new RuntimeException();
}
}
Ответ 3
Вы можете попробовать установить свой собственный неперехваченный обработчик исключений, однако я настоятельно рекомендую против него. Если у вашего приложения есть части, которые могут быть повреждены, и если это исключение не будет должным образом обработано в месте, где будет разбит ваш код, вся ваша программа будет часто срабатывать.