UncaughtExceptionHandler не перехватывает исключение

Я не уверен, почему метод uncaughtException не вызывается.

static
{
    /**
     * Register a logger for unhandled exceptions.
     */
    Thread.UncaughtExceptionHandler globalExceptionHandler = new Thread.UncaughtExceptionHandler()
    {
        @Override
        public void uncaughtException(Thread t, Throwable e)
        {
            System.out.println("handle exception."); // can also set bp here that is not hit.
        }
    };

    Thread.setDefaultUncaughtExceptionHandler(globalExceptionHandler);
    Thread.currentThread().setUncaughtExceptionHandler(globalExceptionHandler);

    /**
     * Register gateway listen port.
     */
    try
    {
       // some stuff that raises an IOException
    }
    catch (IOException e)
    {
        System.out.println("Throwing exception");
        throw new RuntimeException(e);
    }

}

Вывод программы:

Выброс исключения

java.lang.ExceptionInInitializerError
Caused by: java.lang.RuntimeException: java.io.FileNotFoundException: blah.jks 
    (The system cannot find the file specified)
...some stack trace...
Exception in thread "main" 
Process finished with exit code 1

person Dejas    schedule 29.12.2014    source источник
comment
Раздел статистики особенно опасен в JVM, поскольку это начальный раздел для класса, поэтому я думаю, что это действительно зависит от реализации JDK. Например, мой Oracle JDK 1.7.0_65 правильно обрабатывает исключение.   -  person terma    schedule 30.12.2014
comment
Вероятно, потому что исключение обрабатывается правильно, т.е. поток завершается. Я бы не стал использовать эту обработку, если вы фактически не создаете потоки вне основного потока.   -  person Maarten Bodewes    schedule 30.12.2014


Ответы (3)


RuntimeException поднимается из статического инициализатора, это происходит, когда загружается ваш основной класс. Затем он перехватывается загрузчиком системных классов, который заключает его в ExceptionInInitializerError, а затем выходит из JVM. Поскольку исключение перехвачено, ваш обработчик необработанных исключений по умолчанию никогда не вызывается.

person Lolo    schedule 29.12.2014

Ваш код выдает IOException, а ваш catch ловит IOException. IOException пойман и обработан. IIRC UncaughtExceptionHandler имеет дело только с необработанным исключением из обычного кода, а не из catch. Попробуйте временно изменить catch, чтобы поймать другое исключение, и посмотрите, что произойдет. Не забудьте потом поменять обратно!

person rossum    schedule 29.12.2014

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

Так что, если это справедливо, переместите свой код в блок экземпляров, и он должен работать нормально.

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

person Jimmy    schedule 29.12.2014