Подтвердить что ты не робот

Открытый 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

}
4b9b3361

Ответ 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

Вы можете попробовать установить свой собственный неперехваченный обработчик исключений, однако я настоятельно рекомендую против него. Если у вашего приложения есть части, которые могут быть повреждены, и если это исключение не будет должным образом обработано в месте, где будет разбит ваш код, вся ваша программа будет часто срабатывать.